Schemamigration runs for existing columns in the application - python

Assume I am having a Django app named animals. The app has a model named "mammal" as below
class Mammal(models.Model)
name = models.CharField(max_length=256)
is_active = models.BooleanField(default=True)
date_added = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(auto_now=True)
I run a schema migration for the above model
./manage.py schemamigration mammal --initial
An initial migration file gets created and then I migrate it as follows
./manage.py migrate mammal
Now I update the model and add a field mammal_type as below
class Mammal(models.Model)
name = models.CharField(max_length=256)
mammal_type = models.CharField(max_length=63, choices=TYPE_CHOICES, default=TYPE_MAMMAL)
is_active = models.BooleanField(default=True)
date_added = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(auto_now=True)
I again run a schema migration for the above model
./manage.py schemamigration mammal --auto
./manage.py migrate mammal
Everything goes fine. Now comes the issue. I add another field extinct as below
class Mammal(models.Model)
name = models.CharField(max_length=256)
mammal_type = models.CharField(max_length=63, choices=TYPE_CHOICES, default=TYPE_MAMMAL)
extinct = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
date_added = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(auto_now=True)
I run a schema migration
./manage.py schemamigration mammal --auto
The new migration file contains schema migration for previously added mammal_type field which actually should not be present. I am not sure why this happens.
I have tried running field specific schema migrations which allows me to add migrations for just that field, but when it comes to creating M2M tables on the fly, field specific schema migrations do not help. I would need to run schema migration for the entire app for the M2M tables to be created.
Please advice

Related

Django: 0001_initial.py is not on current status after complementing models.py

I am new to Django/python and I am facing a problem with my models.py.
I added some attributes, saved it -> py manage.py makemigrations -> py manage.py migrate
but the current attributes are not shown in the 0001_initial.py.
Also when I am opening the database in my DB Browser for SQLite I still get the old status.
Here's my code:
models.py
from django.db import models
# from django.contrib.auth.models import User
# Create your models here.
category_choice = (
('Allgemein', 'Allgemein'),
('Erkältung', 'Erkältung'),
('Salben & Verbände', 'Salben & Verbände'),
)
class medicament(models.Model):
PZN = models.CharField(max_length=5, primary_key=True) # Maxlaenge auf 5 aendern
name = models.CharField('Medikament Name', max_length=100)
description = models.CharField('Medikament Beschreibung', max_length=500)
category = models.CharField(max_length=100, blank=True, null=True, choices=category_choice)
instructionsForUse = models.CharField('Medikament Einnehmhinweise', max_length=400)
productimage = models.ImageField(null=True, blank=True, upload_to="images/")
stock = models.PositiveIntegerField(default='0')
reorder_level = models.IntegerField(default='0', blank=True, null=True)
price= models.DecimalField(default='0.0', max_digits=10, decimal_places=2)
sold_amount = models.IntegerField(default='0', blank=True, null=True)
sales_volume = models.DecimalField(default='0.0', max_digits=10, decimal_places=2)
def __str__(self):
return self.name
And the 0001_initial.py
# Generated by Django 3.2.16 on 2023-01-05 14:33
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='medicament',
fields=[
('PZN', models.CharField(max_length=5, primary_key=True, serialize=False)),
('name', models.CharField(max_length=100, verbose_name='Medikament Name')),
('description', models.CharField(max_length=500, verbose_name='Medikament Beschreibung')),
('category', models.CharField(default='Allgemein', max_length=100)),
('instructionsForUse', models.CharField(max_length=400, verbose_name='Medikament Einnehmhinweise')),
('productimage', models.ImageField(blank=True, null=True, upload_to='images/')),
('stock', models.IntegerField(default='0')),
],
),
]
First a basic explanation and below an answer to your specific situation
There is 2 steps:
"makemigrations" scans your code, finds changes in models an will create migrations files according to changes like
001_initial.py
002_auto_xyz.....py
There is an initial file and then subsequent migration files having a running number and depend on each other which you can see in the file e.g.
dependencies = [
('users', '0003_auto_20210223_1655'),
]
Once a migration file is created it will not change anymore and all later modifications in the code will be reflected in new additional migrations file after a new makemigration is executed.
"migrate" will take the created migration files, will check your database which migrations have been applied already to this specific database(!) and apply the once that are pending. In the database there is a table created that stores info about the already applied migrations.
That means for example you can run a migrate on a database on your development server and independent from that run migrate on a database on your production server. Both migrate commands will read the existing migration files and perform migrations in the database.
So if you made an initial model -> makemigrations -> migrate, you will see an 001_initial.py migrations file.
If you make changes to the models -> makemigrations again -> migrate again you should find only the changes in the 002_... migrations file and find also the changes in your database.
In any Django project, you only run makemigrations once (at the first initialization of your models), after that you run ONLY migrate for any updates.
As for your problems, you should delete your SQLite DB, and also delete all migrations files that end with .pyc.
After that run makemigrations then migrate, (and don't run makemigrations again, the reason being that it will cause problems and collisions with older SQL migrations based on the previous makemigrations).

Profile table not being created for extended User model in django

I am facing this problem in django where even though there is a Profile model in my models.py file which extends the django User model still on running the 'makemigration' and 'migrate' commands the Profile table is not being generated in database.
This is my models.py:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
clg_name = models.CharField(max_length=200)
class Student(models.Model):
name = models.CharField(max_length=100, blank=False)
enrollment_number = models.IntegerField(unique=True, null=True, blank=False)
clg_name = models.CharField(max_length=200, blank=False)
program_name = models.CharField(max_length=30, blank=False)
class Result(models.Model):
student = models.ForeignKey(Student, on_delete=models.CASCADE)
sem = models.IntegerField()
exam_name = models.CharField(max_length=30)
percnt = models.FloatField(null=True)
cgpa = models.FloatField(null=True)
class Marks(models.Model):
result = models.ForeignKey(Result, on_delete=models.CASCADE)
course_name = models.CharField(max_length=100, null=True)
course_code = models.IntegerField(null=True)
course_credit = models.IntegerField(null=True)
grade = models.FloatField(null=True)
Here is the output of py manage.py makemigration account:
Migrations for 'account':
account\migrations\0001_initial.py
- Create model Result
- Create model Profile
- Create model Marks
And this is the output of py manage.py migrate:
Operations to perform:
Apply all migrations: account, admin, auth, contenttypes, sessions
Running migrations:
No migrations to apply.
I don't know what is wrong with your account app . but you can solve it with :
1- delete __pycache__ and migrations folders located inside account app
2 - run python manage.py makemigrations account zero
3 - then run python manage.py makemigrations account
4 - finally run python manage.py migrate
I solved the following error by just dropping the whole Database and deleting the py_cache and migration files of my application. Just create another database and rerun the migration and migrate commands. Hope this helps.

How to update Django model max_length value in database after tables have already been migrated

I need more characters available for the title and subtitle fields of a blog I made. I would like to increase the max_length from 100 to 150. Here is the table:
class Post(models.Model):
title = models.CharField(max_length=100)
subtitle = models.CharField(max_length=100)
slug = models.SlugField(max_length=99)
date_added = models.DateTimeField(default=timezone.now)
author = models.CharField(max_length=60)
body = models.TextField()
category = models.ForeignKey(Category, on_delete=models.CASCADE)
tags = models.ManyToManyField(Tag)
Through another Q&A I took the advice to change the max_length in the model (in my case from 100 to 150) and type this in the command prompt:
python manage.py makemigrations
python manage.py migrate
I then committed the changes and it allowed me to type more characters in but when I submitted the post it came up with a database error saying the fields can only take 100 characters.
How can I get the database to recognize the change in max_characters?
You can change it and re run the migrations again or do python manage.py migrate my_app 0008_previous_migration you can then delete the newer migration file with the error in it and re run the commands.
You can do python manage.py showmigrations my_app

difficulty in updating csv file

I tried to update the CSV file with a description column. I tried to add an update to the model by adding description = models.CharField(max_length=200, default='SOME STRING') like this:
wine = models.ForeignKey(Wine)
pub_date = models.DateTimeField('date published')
user_name = models.CharField(max_length=100)
comment = models.CharField(max_length=200)
rating = models.IntegerField(choices=RATING_CHOICES)
description = models.CharField(max_length=200, default='SOME STRING')
When I run migrate for this change I get the following error:
c:\Users\Amira Joshi\Desktop\winerama>python manage.py makemigrations
Migrations for 'reviews':
reviews\migrations\0002_review_description.py
- Add field description to review
How can I solve it? Please help!
This is not an error:
c:\Users\Amira Joshi\Desktop\winerama>python manage.py makemigrations
Migrations for 'reviews': reviews\migrations\0002_review_description.py
- Add field description to review
With this django says that the migration file is created, now you must apply the migration by running this command:
python manage.py migrate

Django ForeignKey to AbstractBaseUser

I'm trying to set up an app that will handle reviews about registered users. So in my Review model, I want to have a ForeignKey to my User model.
I'm using a custom user profile that looks like this:
#In /profiles/models.py
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
company = models.CharField(default="", max_length=200)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = MyUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['company']
I have included it with settings.py AUTH_USER_MODEL = "profiles.MyUser". It works fine with registration, creating users etc. So I know its working.
In my review model I write the following:
class Review(models.Model):
company = models.ForeignKey(settings.AUTH_USER_MODEL)
reviewer = models.ForeignKey(Reviewer)
rating = models.IntegerField(default=0)
review = models.TextField()
pub_date = models.DateTimeField('date published')
Instead of settings.AUTH_USER_MODEL I have also tried writing profiles.MyUser, 'profiles.MyUser' and MyUser.
I can successfully use the python manage.py makemigrations reviews command. But when I do python manage.py migrate I get errors no matter what version I use above.
The error I get is the following:
ValueError: Lookup failed for model referenced by field reviews.Review.company: profiles.MyUser
nejc92 comment was correct. I had migrated my database earlier before I set AUTH_USER_MODEL for the first time.
I removed my whole database and created new migrations for all apps and migrated everything again from scratch. It then worked.
Sounds like a bug(?) to me.

Categories

Resources