I am new in peewee and I am very confused about migration. I tried the examples in the official documentation, and I got the results as follows:
from playhouse.migrate import *
from peewee import *
my_db = SqliteDatabase('my_database.db')
migrator = SqliteMigrator(my_db)
from peewee import *
database = SqliteDatabase('my_database.db')
class BaseModel(Model):
class Meta:
database = database
class Product(BaseModel):
name = TextField()
class Meta:
table_name = 'product'
with my_db:
my_db.create_tables([Product,])
Product.create(name = 'Big Peach')
price_field = IntegerField(default=0)
migrate(migrator.add_column('product', 'price', price_field))
db = migrator.database
columns = db.get_columns('product')
print(columns)
Here's what I got and the field of 'price' was added, indicating that migrated () is doing well:
[ColumnMetadata(name='id', data_type='INTEGER', null=False, primary_key=True, table='product', default=None),
ColumnMetadata(name='name', data_type='TEXT', null=False, primary_key=False, table='product', default=None),
ColumnMetadata(name='price', data_type='INTEGER', null=False, primary_key=False, table='product', default=None)]
Now the problem is that when I call Product.price,
query = Product.get(Product.name == 'Big Peach')
print(query.price)
the following result appears:
'Product' object has no attribute 'price'
I've tried another way to do this, in the command line:
python -m pwiz -e sqlite my_database.db
I got this:
from peewee import *
database = SqliteDatabase('my_database.db')
class UnknownField(object):
def __init__(self, *_, **__): pass
class BaseModel(Model):
class Meta:
database = database
class Product(BaseModel):
name = CharField()
price = IntegerField()
class Meta:
table_name = 'product'
I can use these to replace the previous Model, but there's no need to migrate().
So, my confusion is how to call the new field added by using migrate() in ONE .py file.
It's unusual to do this online:
declare a model/schema
migrate it
use the new schema
Because if you know you need a price field just put it on the model class from the start.
If you really need to do this, then you can call this after you've run the migration:
Product._meta.add_field('price', price_field)
Related
I use django-admin-sortable 2.1.2 and django 1.11.
The problem is that the order is not saving when I try to change it from my admin panel. I think this may be due to already existing model instances.
Here is the part of my current code:
// models.py
class Category(SortableMixin):
name = models.CharField(
_('name'),
max_length=150,
)
order = models.PositiveIntegerField(
default=0,
db_index=True,
)
class Meta:
verbose_name = _('category')
verbose_name_plural = _('categories')
ordering = ['order']
// admin.py
class CategoryAdmin(SortableModelAdmin):
class Meta:
model = Category
fields = (
'name',
)
sortable = 'order'
The default value is set as 0 because of already existing objects. I tried to change their order manually in shell console but it did not help.
I want to avoid deleting my objects and creating them again.
Do you have any ideas how to fix this?
I decided to use another class to inheritance from in my admin.py file.
Instead of:
from suit.admin import SortableModelAdmin
class CategoryAdmin(SortableModelAdmin):
class Meta:
model = Category
fields = (
'name',
)
sortable = 'order'
I use:
from adminsortable.admin import SortableAdmin
class CategoryAdmin(SortableAdmin):
class Meta:
model = Category
fields = (
'name',
)
sortable = 'order'
It works a little different but the effect is satisfying for me and solves my problem.
I'm stuck with (I think) a dummy error on Django that I can't find where it's the fault.
On "catalog/models.py" I have (it connects to a MySQL database):
from django.db import models
class Application(models.Model):
nameApp = models.CharField(max_length=50)
tarification = models.ForeignKey(Tarification)
Then, I'm using django-tables2 (Doc to fill tables) to make tables on Django, so on my tables.py I have:
import django_tables2 as tables
from catalog.models import AppCost, Application, Tarification
class BillTable(tables.Table):
class Meta:
appName = Application.nameApp
userApp = AppCost.userApp
tarifName = Tarification.nameTarif
tarifCost = Tarification.cost
startTime = AppCost.startTime
finishTime = AppCost.finishTime
totalCost = AppCost.totalCost
# add class="paleblue" to <table> tag
attrs = {'class': 'paleblue'}
And I get an error when I render my website:
type object 'Application' has no attribute 'nameApp'
On the line appName = Application.nameApp from BillTable
But, looking at "Database" window on Pycharm I see the table schema and it's:
catalog_application
id
tarification_id
nameApp
other stuff
And looking with MySQL Workbench the schema looks the same. So, why I'm getting this error?
Regards.
As Daniel Roseman mentioned above, the code you might looking for is below, it does not need a new model:
import django_tables2 as tables
from catalog.models import AppCost, Application, Tarification
class AppCostTable(tables.Table):
userApp = tables.Column()
startTime = tables.Column()
finishTime = tables.Column()
totalCost = tables.Column()
class Meta:
model = AppCost
class ApplicationTable(tables.Table):
appName = tables.Column(accessor='nameApp')
class Meta:
model = Application
class TarificationTable(tables.Table):
tarifName = tables.Column(accessor='nameTarif')
tarifCost = tables.Column(accessor='cost')
class Meta:
model = Tarification
class BillTable(AppCostTable, ApplicationTable, TarificationTable, tables.Table):
pass
If you do not mind to have another model, then inside your catalog.models you can add a new Bill model:
class Bill(models.Model):
application = models.ForeignKey('Application')
appcost = models.ForeignKey('AppCost')
tarification = models.ForeignKey('Tarification')
In your table file:
from catalog.models import Bill
class BillTable(tables.Table):
appName = tables.Column(accessor='application.nameApp')
tarifName = tables.Column(accessor='tarification.nameTarif')
tarifCost = tables.Column(accessor='tarification.cost')
userApp = tables.Column(accessor='appcost.userApp')
startTime = tables.Column(accessor='appcost.startTime')
finishTime = tables.Column(accessor='appcost.finishTime')
totalCost = tables.Column(accessor='appcost.totalCost')
class Meta:
model = Bill
You're very confused about how to use django-tables. You need to specify one model in the Meta class, then just the fields attribute to add a list of fields from that model, as strings, to display. You can't just specify fields from three arbitrary models.
I'm working now on my first Django project. I want to render results table which contains all fields from Priekabos model and one custom column from Grafikas which should contain something similar to:
SELECT max(kada_moketi) FROM grafikas WHERE priekabos_id = ?
Whatever I try from examples nothing works. Should I write another view function with that custom query:
(Grafikas.objects.filter(priekabos_id=1)
neither with:
.aggregate(Max('kada_moketi')
neither with:
.latest('kada_moketi')
worked for me I created a new table class in tables.py which later PriekabosTable will inherit? That didn't work for me too.
Here's my code:
models.py
class Grafikas(models.Model):
id = models.AutoField(primary_key=True)
mokejimo_nr = models.IntegerField()
kada_moketi = models.DateField()
priekabos = models.ForeignKey('Priekabos', models.DO_NOTHING)
class Priekabos(models.Model):
id = models.AutoField(primary_key=True)
sutarties_nr = models.CharField(unique=True, max_length=45, verbose_name='Sut. Nr.')
nuomos_pradz = models.DateField()
sutarties_trukme = models.IntegerField()
views.py
def priekabos_table(request):
table = PriekabosTable(Priekabos.objects.all())
RequestConfig(request, paginate={'per_page': 20}).configure(table)
return render(request, 'isperkamoji_nuoma/priekabos_table.html', {'table': table})
tables.py
class PriekabosTable(tables.Table):
class Meta:
model = Priekabos
attrs = {"class": "paleblue"}
fields = ('id', 'sutarties_nr', 'nuomos_pradz')
For better understanding, here's 'grafikas' table:
MySQL 'grafikas' table
It sounds like you might be able to fetch the extra field using annotate.
from django.db.models import Max
queryset = Priekabos.objects.annotate(max_kada_moketi=Max('grafikas__kada_moketi'))
table = PriekabosTable(queryset)
Remember to add the field to your table.
class PriekabosTable(tables.Table):
class Meta:
model = Priekabos
attrs = {"class": "paleblue"}
fields = ('id', 'sutarties_nr', 'nuomos_pradz', 'max_kada_moketi')
I'am trying to make a queryset in django but i'am without luck.
for some reason my model seems to be wrong.
I'll simplify.
I have this Classes in the models.py:
class RcAnalysis(models.Model):
id = models.AutoField(db_column='Id', primary_key = True) # Field name made lowercase.
/*
some other 10 columns (srry can't post here)
*/
class Meta:
db_table = 'rc_Analysis'
class RcAnalysistag(models.Model):
analysisid = models.ForeignKey(RcAnalysis, db_column='AnalysisId') # Field name made lowercase.
tagid = models.ForeignKey(LabTags, db_column='TagId') # Field name made lowercase.
class Meta:
db_table = 'rc_AnalysisTag'
I need to join the RcAnalysis with analysistag model.
But i dont have a field that i can call RcAnalysisTag proper.
Its like this SQL query:
...
from rc_Analysis A
...
inner join rc_AnalysisTag At on ( A.Id = At.AnalysisId )
inner join lab_Tags T on ( T.Id = At.TagId )
Someone?
Add a related_name="tags" to the foreign key definition. Then you can do:
analysis_object = RCAnalysis.object.get(id=1)
related_tags = analysis_object.tags.all()
I am new to peewee, so please forgive me if this is a stupid question. I have searched on Google and in the peewee cookbook, but found no solution so far.
So, I have the following models to four of my DB tables:
class games_def(Model):
id = PrimaryKeyField()
name = TextField()
class Meta:
database = dbmgr.DB
class users_def(Model):
id = PrimaryKeyField()
first_name = TextField()
last_name = TextField()
class Meta:
database = dbmgr.DB
class sessions(Model):
id = PrimaryKeyField()
game = ForeignKeyField(games_def, related_name = 'sessions')
user = ForeignKeyField(users_def, related_name = 'sessions')
comment = TextField()
class Meta:
database = dbmgr.DB
class world_states(Model):
session = ForeignKeyField(sessions)
time_step = IntegerField()
world_state = TextField()
class Meta:
database = dbmgr.DB
Using these models I connect to an SQLite3 DB via peewee, which works fine.
After the connection has been established I do the following in my main Python code:
models.world_states.create(session = 1, time_step = 1)
However, this gives me the following error:
sqlite3.OperationalError: table world_states has no column named session_id
That is basically correct, the table world_state does indeed not contain such a column.
However, I cannot find any reference to "session_id" in my code at all.
Whe does peewee want to use that "session_id" colum name?
Do I miss something essentially here?
When you specify a ForeignKeyField() peewee expects to use a column ending in _id based on their own name. Your wold_states.session field thus results in an column named session_id.
You can override this by setting db_column for that field:
class world_states(Model):
session = ForeignKeyField(sessions, db_column='session')