Enum field in MySQL - python

In MySQL there are several types of data, char, varchar int, boolean as you already know.
But it also has the Enum type that in SQL we create the table as follows:
CREATE TABLE person(
id int.....
name varchar(50),
and
Married Enum(Yes,No)
)
My goal is, when I'm creating the models in Django (Python) to be able to create the tables in MySQL I can automatically create this type of field as well.
I tried like this:
from django.db import models
from enum import enum
class options(Enum):
Yes = "Yes"
No = "No"
class Customer(models.Model) :
name = models.CharField(max_length=200)
docto = models.CharField(max_length=14)
age = models.IntegerField(default=0)
username = models.CharField(max_length=20)
password = models.CharField(max_length=20)
block = models.CharField(
max_length=3,
choices=[(tag, tag.value) for tag in options],
default= 'No'
)
def __str__(self):
return self.name
Create the field in MySQL creates but creates as VARCHAR(3) and not as enum.
Can Django do this? How would it be?
I wouldn't like to have to create the tables directly in the database,

Related

How to use `migrate()` in Peewee

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)

How to create a Object that has PrimaryKeyField and ForeignKeyField ? Python Flask PeeWee

the classes:
class User(flask_db.Model, UserMixin):
id = PrimaryKeyField()
social_id = CharField(null=False, unique=True)
nickname = CharField(null=False)
email = CharField(null=True)
class Feed(flask_db.Model):
id = PrimaryKeyField()
user = ForeignKeyField(User, related_name='feeds')
title = CharField()
url = CharField()
description = CharField()
If I do something like:
newfeed = Feed.create(..)
What should I put in the type id and in the type user ?
How should I get all the feeds of a User ?
With something like this ?
feedsofuserTom = Feed.select().where(Feed.user == userTom)
I don't understand the ForeignKeyField() function, I read the documentation but the examples didn't work for me. http://docs.peewee-orm.com/en/latest/peewee/models.html
ForeignKey is a relation between models.
ForeignKey is ManyToOne relation.
So for your Feed you can relate as many Users as you want.
So in your example firstly you have to create User instanse. And then add it while creating Feed.
first_user = User.create(social_id=1, nickname=name, email="email")
newfeed = Feed.create(user=first_user, title="cool feed", url="url.com", description="description")
As far as i remember you don't have to add PrimaryKeyField(). This field will be added automatically by database.

Add columns to queryset and django-table2 table

I have the following model and table;
class Person(models.Model):
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
user = models.ForeignKey("auth.User")
dob = models.DateField()
# tables.py
class PersonTable(tables.Table):
class Meta:
model = Person
I want to generate a SQL query to calculate the updated age of every Person on my MySQL DB on the fly, using 'dob' every time I retrieve objects, is it possible with django?
Moreover, if i can generate the sql query with aditional column "age" how can I add it to the table?
I am wondering if i should use django-table2 in this case.
EDIT: I've solved doing this way.
I've created a function on MYSQL for calculating age based on a arg type date.
Then I've use this function in an raw sql query in my view.
def get_persons(request):
list_people = Person.objects.raw("SELECT *, age(date_birth) AS edad FROM mytable)
For adding this new age column to my table I've created a new Table class and added two columns "age" and "detail", like this:
class TablaBeneficiarios(tables.Table):
age= tables.Column(orderable=True,verbose_name= "Age")
detail= tables.TemplateColumn('Ver',verbose_name="Acciones") #just a link column
class Meta:
model = FormularioA
attrs = {"class": "paleblue"}
fields = ("cod_pais", "num_familia", "num_miem_familia","fecha_ingreso_ret", "nombre", "prim_apellido",
"seg_apellido", "sexo", "etnia", "responsable", "age","detail")
Thanks in advance.
class Person(models.Model):
# ...
#property age(self):
result_age = 'some queryset that return one column and one row' or datetime.date.today() - self.dob
return result_age
class PersonTable(tables.Table):
age = tables.Column('Custom name', order_by=('dob', )) # you cannot order by property, so put dob or orderable=False
class Meta:
model = Person

SQLite3 OperationalError: Table XYZ has no column named ABC

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')

How to describe m2m triple-join table in model (Django)

My question is pretty much the same as this question, except that ALL relationships should be many-to-many.
I have the following classes in my models.py (somewhat simplified):
class Profile(models.Model):
# Extending the built in User model
user = models.ForeignKey(User, unique=True)
birthday = models.DateField()
class Media(models.Model):
title = models.CharField(max_length=200)
description = models.TextField(max_length=2000)
class Role(models.Model):
name = models.CharField(max_length=50)
What I want is a junction table that looks something like this:
CREATE TABLE `media_roles` (
`media_id` bigint(20) unsigned NOT NULL,
`profile_id` bigint(20) unsigned NOT NULL,
`role_id` bigint(20) unsigned NOT NULL
)
John Doe - Director, Writer, Producer
Jane Doe - Executive Producer
...
This is what I've used so far:
class MediaRole(models.Model):
media = models.ForeignKey(Media)
user = models.ForeignKey(Profile)
role = models.ForeignKey(Role)
But isn't there any better way of doing this, not involving the creation of a separate class in the model?
What about separating the two m2m relationships?
class Profile(models.Model):
...
medias = models.ManyToManyField(Media, related_name='profiles')
roles = models.ManyToManyField(Role, related_name='profiles')
In this way Django create two association tables for you, and you can utilize the convenient related fields like this:
profile = Profile.objects.get(user=someone)
print profile.medias.all()
print profile.roles.all()

Categories