Django - Charfield creates an item int my BD - mysql

I have a simple project here, with two models that contain an attribute called telefone in both.
telefone is phone in portuguese.
Code
class Medico (models.Model):
nome = models.CharField(max_length=50)
endereco = models.CharField(max_length=60)
cpf = models.CharField(unique=True, max_length=11)
telefone = models.CharField(max_length=15)
especialidade = models.ForeignKey(Especialidade, on_delete=models.CASCADE)
def __str__(self):
return self.nome
class Paciente (models.Model):
nome = models.CharField(max_length=50)
endereco = models.CharField(max_length=60)
cpf = models.CharField(unique=True, max_length=11)
telefone = models.CharField(max_length=15)
def __str__(self):
return self.nome
I did the makemigrations and migrate, everything worked as expected, I'm using MySQL as BD.
But for some reason, the phone field is int int in my BD for both the patient table and the medical table, see the image:
Now the other fields are correct, could anyone tell me why this is happening?
EDIT 01:
migrations.CreateModel(
name='Paciente',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nome', models.CharField(max_length=50)),
('endereco', models.CharField(max_length=60)),
('cpf', models.CharField(max_length=11, unique=True)),
('telefone', models.CharField(max_length=15)),
],
),
continue

Delete all the files in yourapp/migrations, except __init__.py
Then run these 2 commands :
python manage.py makemigrations
python manage.py migrate
UPDATE :
If that does not work, delete all tables from MySQL database and let Django recreate them using python manage.py makemigrations and python manage.py migrate

Related

Alembic attempts to recreate all tables in the Base class on every migration

In my env.py I have set my target_metadata to Base.metadata which I import from models.py. I have a fresh database with a schema named basic that I want to use to create the tables and setup my models.py like this:
from datetime import datetime
from sqlalchemy import Column, DateTime, Integer, MetaData, String
from sqlalchemy.orm import declarative_base
Base = declarative_base(metadata=MetaData(schema='basic'))
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False)
created_on = Column(DateTime, default=datetime.utcnow)
I run alembic revision --autogenerate -m"Create user model" and run alembic upgrade heads. Everything works as expected and I have table user in my database under the schema basic.
Now I want to add a table country. I add it to my models.py which now looks like this:
from datetime import datetime
from sqlalchemy import Column, DateTime, Integer, MetaData, String
from sqlalchemy.orm import declarative_base
Base = declarative_base(metadata=MetaData(schema='basic'))
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False)
created_on = Column(DateTime, default=datetime.utcnow)
class Country(Base):
__tablename__ = 'country'
id = Column(Integer, primary_key=True)
country = Column(String, nullable=False)
created_on = Column(DateTime, default=datetime.utcnow)
I run alembic revision --autogenerate -m"Create country model" which creates a new versions file that looks like this:
"""Create country model
Revision ID: 0eef32919b0d
Revises: 2da4668d1069
Create Date: 2023-01-19 15:39:08.778274
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '0eef32919b0d'
down_revision = '2da4668d1069'
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('country',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('country', sa.String(), nullable=False),
sa.Column('created_on', sa.DateTime(), nullable=True),
sa.PrimaryKeyConstraint('id'),
schema='basic'
)
op.create_table('user',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(), nullable=False),
sa.Column('created_on', sa.DateTime(), nullable=True),
sa.PrimaryKeyConstraint('id'),
schema='basic'
)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('user', schema='basic')
op.drop_table('country', schema='basic')
# ### end Alembic commands ###
Why does it also try to create the table user again? Running this will give an error that the object basic.user already exists. How can I fix this so that it looks at the current state of the db and only wants to create the table country?
Setting the option include_schemas=True (which is suggested in this thread: Alembic - sqlalchemy does not detect existing tables) helps but then includes all schemas and I only want it to be aware of this single schema.
I only want it to be aware of this single schema.
Then you also need to use include_name=, like so:
def run_migrations_online():
# …
def include_name(name, type_, parent_names):
if type_ == "schema":
# note this will not include the default schema
return name in ["basic"]
else:
return True
with connectable.connect() as connection:
context.configure(
connection=connection, target_metadata=target_metadata,
include_schemas=True,
include_name=include_name
)

Alembic Revision Autogenerate Didn't Recognized The Default Value Change

I was testing Alembic.
Initially I created a model something like this:
from main import Base
from sqlalchemy import Column, BigInteger, SmallInteger, String, Sequence, ForeignKey
class Users(Base):
__tablename__ = "users"
id = Column(BigInteger, Sequence("user_id_seq"),
primary_key=True)
first_name = Column(String(50))
last_name = Column(String(50))
email = Column(String(255))
password = Column(String(60), nullable=True)
Then I created the revision in alembic and it worked absolutely fine and I got the result properly.
Then I added the user types table and then my models looked like this,
from main import Base
from sqlalchemy import Column, BigInteger, SmallInteger, String, Sequence, ForeignKey
class Users(Base):
__tablename__ = "users"
id = Column(BigInteger, Sequence("user_id_seq"),
primary_key=True)
first_name = Column(String(50))
last_name = Column(String(50))
email = Column(String(255))
password = Column(String(60), nullable=True)
user_type = Column(SmallInteger, ForeignKey(
"user_types.id", name="fk_user_type"))
class UserTypes(Base):
__tablename__ = "user_types"
id = Column(SmallInteger, Sequence("user_types_id_seq"),
primary_key=True)
type = Column(String(20))
Now I created the revision for this and obviously that also worked.
But then I thought that lets make the user_type default value 1. So I did a small change in Users model and added default value 1:
user_type = Column(SmallInteger, ForeignKey(
"user_types.id", name="fk_user_type"), default=1)
Now ideally if I created migration it should work. But it gave me the blank file:
"""Made Default Value Of user_type 1
Revision ID: 054b79123431
Revises: 84bc1adb3e66
Create Date: 2022-12-28 17:20:06.757224
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '054b79123431'
down_revision = '84bc1adb3e66'
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
I also tried to add compare_server_default=True in the context.configure calls in both offline and online migration function as it was said in an answer I found on internet which was related to the same issue but that also didnt worked. Here is the link.
So if anyone knows the solution for this please tell me I would really be thankful to you!

How to make the id auto increasing by 2 in the Model of Django?

Since the auto_increment setting in the MySQL is for the global, which cannot be set to a specific table?
I'm considering if it's possible to make the id auto increasing by 2 in the Model of Django?
models.py
class Video(models.Model):
name = model.CharField(max_length=100, default='')
upload_time = models.DateTimeField(blank=True, null=True)
def __str__(self):
return self.name
What should I do? Thanks for ur help.
You could do it my overriding save() method of your model as
from django.db.models import Max, F
class Video(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100, default='')
upload_time = models.DateTimeField(blank=True, null=True)
def save(self, *args, **kwargs):
if not self.pk:
max = Video.objects.aggregate(max=Max(F('id')))['max']
self.id = max + 2 if max else 1 # if the DB is empty
super().save(*args, **kwargs)
def __str__(self):
return self.name
the correct way is to change your mysql server settings
check this out: auto_increment_increment
Possible Solutions:
Assume I have a Model of Customer.
Customer.objects.order_by('primay_key_id ').last().primay_key_id + 2)
primay_key_id = models.IntegerField(default=(Customer.objects.order_by('primay_key_id ').last().primay_key_id + 2),primary_key=True)
or
from django.db import transaction
#Uncomment Lines for Django version less than 2.0
def save(self):
"Get last value of Code and Number from database, and increment before save"
#with transaction.atomic():
#top = Customer.objects.select_for_update(nowait=True).order_by('-customer_customerid')[0] #Ensures Lock on Database
top = Customer.objects.order_by('-id')[0]
self.id = top.id + 1
super(Customer, self).save()
The Above Code would not have a Concurrency Issue for Django 2.0 as:
As of Django 2.0, related rows are locked by default (not sure what the behaviour was before) and the rows to lock can be specified in the same style as select_related using the of parameter!
For Lower Versions, you need to be atomic!
or
from django.db import transaction
def increment():
with transaction.atomic():
ids = Customer.objects.all()
length = len(ids)-1
if(length<=0): #Changed to Handle empty Entries
return 1
else:
id = ids[length].customer_customerid
return id+2
or
from django.db import transaction
def increment():
with transaction.atomic():
return Customer.objects.select_for_update(nowait=True).order_by('-customer_customerid')[0] #Ensures Atomic Approach!
and set primary key in model to Integer Field and on every new entry primary_key_field=increment() Like
and then in your Models.py
set the Primary_Key to:
import increment()
primay_key_id = models.IntegerField(default=increment(),primary_key=True)

sqlalchemy ORM : how to declare a table class that contains multiple key?

I'm a newbie in Sqlalchemy.
I have a table with multiple key in column USERNAME.
This is what I've done in my model.
Model:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root#localhost/admin'
db = SQLAlchemy(app)
class RADUSAGE(db.Model):
__tablename__ = 'RADUSAGE'
USERNAME = db.Column(db.String(513))
AGE = db.Column(db.Integer)
def __init__(self, USERNAME, AGE):
self.USERNAME = USERNAME
self.AGE = AGE
def __repr__(self):
return '<RADUSAGE %r>' % self.USERNAME
But I got an error:
File "/Users/admin/rad_env/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 530, in map
**self.mapper_args
File "<string>", line 2, in mapper
File "/Users/admin/rad_env/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 677, in __init__
self._configure_pks()
File "/Users/admin/rad_env/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 1277, in _configure_pks
(self, self.mapped_table.description))
sqlalchemy.exc.ArgumentError: Mapper Mapper|RADUSAGE|RADUSAGE could not assemble any primary key columns for mapped table 'RADUSAGE'
How can I declare this table class that contains multiple key in sqlalchemy? Hope someone can help me. Thanks in advance.
You should be able to specify primary_key=true in your mapping for each PK column:
USERNAME = db.Column(db.String(513), primary_key=True)
AGE = db.Column(db.Integer, primary_key=True)
Did you try that?

Working with sorl-thumbnail and Django Admin

I get this error "employee_directory.thumbnail_kvstore' doesn't exist" when I use sorl-thumbnail to try and format my django admin profile image. Has anyone ran into this while working with sorl-thumbnail and django admin changelist?
DatabaseError at /directory/employee/
(1146, "Table 'employee_directory.thumbnail_kvstore' doesn't exist")
I doubled checked my sorl-thumbnail installation, and made sure I did a syncdb. Below is the code from my models.py and admin.py
models.py:
from django.db import models
from sorl.thumbnail import ImageField
# Department Table
class Department(models.Model):
department_name = models.CharField(max_length=128)
def __unicode__(self):
return self.department_name
# Employee Directory Table
class Employee(models.Model):
last_name = models.CharField(max_length=32)
first_name = models.CharField(max_length=32)
profile_image = models.ImageField(upload_to="images/profile_image", blank=True)
department_name = models.ForeignKey('Department')
job_title = models.CharField(max_length=64)
office_number = models.CharField(max_length=8, blank=True)
fax_number = models.CharField(max_length=8, blank=True)
mobile_number = models.CharField(max_length=8, blank=True)
intercom_number = models.CharField(max_length=3, blank=True)
email = models.CharField(max_length=128)
memo = models.TextField(blank=True)
def __unicode__(self):
return self.last_name + ', ' + self.first_name
admin.py:
from directory.models import *
from django.contrib import admin
from sorl.thumbnail import get_thumbnail
class EmployeeAdmin(admin.ModelAdmin):
def profile_img(self, obj):
if obj.profile_image:
t = get_thumbnail(obj.profile_image,"50x50",crop='center', quality=99)
return u'<img src="/media%s"/>' % t.url
else:
return u'profile_image'
profile_img.short_description = 'Profile image'
profile_img.allow_tags = True
search_fields = ['last_name', 'first_name']
list_display = ['profile_img', 'last_name', 'first_name', 'department_name',
'job_title', 'office_number', 'fax_number',
'mobile_number', 'intercom_number', 'email']
list_filter = ['department_name']
admin.site.register(Department)
admin.site.register(Employee, EmployeeAdmin)
Any help is greatly appreciated.
I totally noobed out, I forgot to put sorl.thumbnail in my apps in the django settings.