I've recently migrated to postgresql, I was not sure about the cause of the problem but column does not exist error is showing up.
ProgrammingError at /admin/mtsauth/authorms/
column mtsauth_authorms.nihgrants does not exist
LINE 1: ..."secfirstname", "mtsauth_authorms"."seclastname", "mtsauth_a...
this is migrations file
migrations.CreateModel(
name='AuthorMS',
fields=[
('firstname', models.CharField(max_length=120)),
('lastname', models.CharField(max_length=120)),
('ArticleId', models.AutoField(primary_key=True, `enter code here`serialize=False)),
('secfirstname', models.CharField(blank=True, default='None', max_length=120)),
('seclastname', models.CharField(blank=True, default='None', max_length=120)),
('nihgrants', models.BooleanField(default=False)),
('country', models.CharField(choices=[('INDIA', 'INDIA'), ('US', 'USA'), ('UK', 'UK'), ('RUSSIA', 'RUSSIA')], max_length=50)),
('seccountry', models.CharField(blank=True, choices=[('INDIA', 'INDIA'), ('US', 'USA'), ('UK', 'UK'), ('RUSSIA', 'RUSSIA')], default='None', max_length=50)),
('affliation', models.CharField(default='None', max_length=100)),
('secAffliation', models.CharField(blank=True, default='None', max_length=100)),
('code', models.IntegerField(default=101, max_length=10000)),
],
),
Your changes are not fully reflected in the database. This could be because you have not migrated to the database. Be sure you provide value for non-nullable fields to your model by giving them a default value. You can check the status of a migration by running the following command:
python manage.py showmigrations <your_app_name>
This will show the list of migrations. The one without the X to the left of migration is the one you have missed to migrate.
Comment all your urls.py lines. Including all imports. Except:
from django.contrib import admin
from django.urls import path
admin = [
path('admin/', admin.site.urls),
]
In terminal run
python manage.py makemigrations
python manage.py migrate
Solved.
Related
I need to change a field from
my_boolean = models.BooleanField(verbose_name="Safe Visiting Space", default=False)
to
my_boolean = models.NullBooleanField(verbose_name="Safe Visiting Space", default=None, blank=True, null=True)
So I've made the above change within the model and run makemigrations to create
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('my_app', '0164_auto_20201027_0820'),
]
operations = [
migrations.AlterField(
model_name='mymodel',
name='my_boolean',
field=models.NullBooleanField(default=None, verbose_name='Safe Visiting Space'),
),
]
But this will not set the default of the current 70k records to None but will leave them as False, so I amended the migrations file to
from django.db import migrations, models
from my_app.models import MyModel
def set_my_boolean_default(apps, schema_editor):
objects= MyModel.objects.active().filter(my_boolean=False)
for object in objectss:
object.my_boolean = None
object.save()
class Migration(migrations.Migration):
dependencies = [
('providers', '0164_auto_20201027_0820'),
]
operations = [
migrations.AlterField(
model_name='organisation',
name='infection_control_safe_visiting_space',
field=models.NullBooleanField(default=None, verbose_name='Safe Visiting Space'),
),
migrations.RunPython(set_my_boolean_default),
]
This will take hours to run. Also, a random check of the database and it doesn't seem to be updating any of the records.
What is the right / better way to do this?
It's taking you so long because of this for loop:
objects= MyModel.objects.active().filter(my_boolean=False)
for object in objects:
object.my_boolean = None
object.save() # Database roundtrip
Namely, for each object, you are hitting the database. The better way is to bulk_update the fields all at once:
objects= MyModel.objects.active().filter(my_boolean=False).update(my_boolean=None)
You can perform the query above inside your shell. It's better not to include it in your migration files for it may be executed each time you run migrations.
Enter you Django shell by python manage.py shell, import your model, and execute the query above.
i want to add another initial.py file from makemigrations file
when i try to py manage.py makemigrations it show error
you are trying to add a non-nullable field 'role' to user without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix :
Provide a one-off default now(will be set on all existing rows with a null value for this column)
Quit, and let me add a default in models.py
i want to make another init to make a dependent dropdown
this is what i write in models.py
import datetime
from django.db import models
from django.utils import timezone
class TableAll(models.Model):
table_name = models.CharField(max_length=250)
and this is the code that 0001_initial.py has
# Generated by Django 2.2.2 on 2019-10-29 03:52
from django.db import migrations, models
from django.contrib.auth.models import User
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
role = models.CharField(max_length=250)
role.contribute_to_class(User,'role')
operations = [
migrations.CreateModel(
name='TableAll',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('table_name', models.CharField(max_length=250)),
],
),
]
i want to add a foreign key to another model and want to makemigrations to add a new 00002_initial.py(for example) and i want to have something like this(here is the code i found from github source)
new initial file (0002_add_initial_data.py) //this is just an example from github source code where it has 0001_initial.py and 0002_add_initial_data.py to make the dependent dropdown works
class Migration(migrations.Migration):
Country = apps.get_model('hr', 'Country')
City = apps.get_model('hr', 'City')
india = Country.objects.create(name='India')
City.objects.create(name='Bengaluru', country=india)
City.objects.create(name='Mumbai', country=india)
City.objects.create(name='Chennai', country=india)
City.objects.create(name='Hyderabad', country=india)
City.objects.create(name='New Delhi', country=india)
usa = Country.objects.create(name='United States')
City.objects.create(name='New York', country=usa)
City.objects.create(name='San Francisco', country=usa)
City.objects.create(name='Los Angeles', country=usa)
City.objects.create(name='Chicago', country=usa)
City.objects.create(name='Seattle', country=usa)
russia = Country.objects.create(name='Russia')
City.objects.create(name='Moscow', country=russia)
City.objects.create(name='Saint Petersburg', country=russia)
City.objects.create(name='Yekaterinburg', country=russia)
City.objects.create(name='Kazan', country=russia)
City.objects.create(name='Krasnodar', country=russia)
brazil = Country.objects.create(name='Brazil')
City.objects.create(name='Sao Paulo', country=brazil)
City.objects.create(name='Rio de Janeiro', country=brazil)
City.objects.create(name='Belo Horizonte', country=brazil)
City.objects.create(name='Curitiba', country=brazil)
City.objects.create(name='Recife', country=brazil)
uk = Country.objects.create(name='United Kingdom')
City.objects.create(name='London', country=uk)
City.objects.create(name='Huddersfield', country=uk)
City.objects.create(name='Glasgow', country=uk)
City.objects.create(name='Edinburgh', country=uk)
City.objects.create(name='Cambridge', country=uk)
dependencies = [
('hr', '0001_initial'),
]
operations = [
migrations.RunPython(add_initial_data),
]
Thankyou for the help, im new to this django framework , and i need to use it for my thesis ..
There is a pattern that can be followed when a non-nullable field is being added to a model and the value of that field is the result of a script.
Add the field to your model but make it nullable (null=True)
Run makemigrations to create a migration that adds the nullable field
Create another migration (makemigrations --empty) that fills in this column using migrations.RunPython
Remove null=True from the field and run makemigrations again. When prompted with the selection choose 1 "Provide a one-off default now" and enter any integer you like as all rows should already have a value it will not matter
migrate
class M_Post(models.Model):
''''
CODE
''''
class M_File(models.Model):
....
CODE
....
class M_Post_File(models.Model):
post = models.ForeignKey(M_Post,on_delete=models.CASCADE)
file = models.ForeignKey(M_File,on_delete=models.CASCADE,null=True)
error:
django.db.utils.NotSupportedError: Renaming the 'posts_file' table while in a transaction is not supported on SQLite because it would break referential integrity. Try adding atomic = False to the Migration class.
how to solve this error
Go to related migration file(automatically created in migrations directory after makemigrations command) and add atomic = False to the Migration class. Migration(migrations.Migration):. Then you can migrate the changes.
example code:
# Generated by Django 2.1.14 on 2019-12-02 07:07
from django.db import migrations, models
class Migration(migrations.Migration):
atomic = False # **<<< HERE**
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='ebayLog',
fields=[
If you still have the problem here is a example:
# Generated by Django 2.1 on 2018-08-16 21:22
from django.db import migrations
class Migration(migrations.Migration):
atomic = False # <<<< THIS LINE
dependencies = [
('shop', '0004_product_imgfeat'),
]
operations = [
migrations.RenameModel(
old_name='Category',
new_name='CategoryShop',
),
]
I migrated many times after I got this error.
Then I did what Selim said above and I also added atomic = False after class Migration(migrations.Migration): in every migration file, which was a little silly because I didn't know which file was THE related migration file...
Then I searched the "atomic=False" in Django documentation and I found these:1
2
As the error "Renaming the 'posts_file' table while in a transaction is not supported on SQLite" described we know that renaming while in a transaction is not supported on SQLite, so adding atomic=False is needed. But I don't know about DDL transactions so that's too much for me...
If you don't want to touch anything and you've just started your project (well not necessarily), you can just delete the migration files inside the migrations directory and migrate again.
Otherwise, change the atomic variable in the migrations file to False then you can migrate your changes.
Another way, if atomic=false method didn't work, is you can delete generated files in the migration folder and start again by make migrations and migrate
Iam also getting the same error at categories_coupon model.
Go to app which contains categories_coupon model.
Rename the error raising model. (i renamed the 'coupon' model to 'coupons')
open the migrations folder.
and add 'atomic=False' line to all migrations files whose names related to post_file.
then run makemigrations command.
then run migrate command.
then runserver.
For reference look at my models
0003_coupons.py
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
atomic = False #this is the line i added.
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('categories', '0002_auto_20211008_1305'),
]
operations = [
migrations.CreateModel(
name='Coupons',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(blank=True, max_length=200, null=True)),
('code', models.CharField(blank=True, max_length=200, null=True)),
('description', models.TextField()),
('coupon_type', models.IntegerField(choices=[('%', '%'), ('RS', 'RS')])),
('discount', models.DecimalField(decimal_places=2, default=0, max_digits=20)),
('max_users', models.IntegerField(default=0)),
('used_count', models.IntegerField(default=0)),
('startd_date', models.DateField()),
('end_date', models.DateField()),
('icon', models.FileField(upload_to='uploads/banners')),
('is_active', models.IntegerField(choices=[(1, 'Active'), (2, 'Inactive'), (3, 'Deleted')])),
('created_date', models.DateTimeField(auto_now_add=True)),
('users', models.ManyToManyField(to=settings.AUTH_USER_MODEL)),
],
),
]
0004_rename_coupons_coupon.py
-----------------------------------
from django.conf import settings
from django.db import migrations
class Migration(migrations.Migration):
atomic=False #here is the line i added.
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('categories', '0003_coupons'),
]
operations = [
migrations.RenameModel(
old_name='Coupons',
new_name='Coupon',
),
]
Using migrations, I need to add a new field (a foreign key) to a model. I know it can be done with:
migrations.AddField(
model_name='MyModel',
name='state',
field=models.ForeignKey(null=True, related_name='mymodel_state', to='msqa_common.MyModelState'),
),
However, I don't want my field to be nullable. Instead, I want to use a default value for it, corresponding to the id of MyModelState whose name is "available" (id value might change in different machines). This "available" value of table MyModelState is inserted into the database in a previous migration script, so it does exist.
I guess I should do something like:
migrations.AddField(
model_name='MyModel',
name='state',
field=models.ForeignKey(null=False, default=available_state_id, related_name='mymodel_state', to='msqa_common.MyModelState'),
),
My question: How can I get the available_state_id within my migration script?
You can't do it directly. The recommended way of doing this is to create a migration to add it with null=True, then add a data migration that uses either Python or SQL to update all the existing ones to point to available_state_id, then a third migration that changes it to null=False.
I just had the same issue and stumbled upon this answer, so here is how I did it:
operations = [
# We are forced to create the field as non-nullable before
# assigning each Car to a Brand
migrations.AddField(
model_name="car",
name="brand",
field=models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.PROTECT,
to="model.Brand",
),
),
# assign_car_to_brand loops over all my Car objects and sets their
# "brand" field
migrations.RunPython(add_category_to_tags, do_nothing),
# Make the field non-nullable to force all future Car to have a Brand
migrations.AlterField(
model_name="car",
name="brand",
field=models.ForeignKey(
null=False,
on_delete=django.db.models.deletion.PROTECT,
to="model.Brand",
),
preserve_default=False
),
]
Here is a relatively complete example:
Step One
python manage.py makemigrations, set the temporary default value to None
Step Two
Change the genrated migration code to below style
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
def set_default_author_to_blog(apps, schema_editor):
User = apps.get_model("auth", "User")
Blog = apps.get_model("blog", "Blog")
Blog.objects.update(author=User.objects.first())
def revert_set_default_autor_to_blog(apps, schema_editor):
Blog = apps.get_model("blog", "Blog")
Blog.objects.update(author=None)
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('blog', '0001_auto_20220425_1017'),
]
operations = [
migrations.AddField(
model_name='blog',
name='author',
field=models.ForeignKey(null=True, db_constraint=False, on_delete=django.db.models.deletion.PROTECT,
to='auth.user', verbose_name='Author')
),
migrations.RunPython(set_default_author_to_blog, reverse_code=revert_set_default_autor_to_blog),
migrations.AlterField(
model_name='blog',
name='author',
field=models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.PROTECT,
to='auth.user', verbose_name='Author')
),
]
Step Three
python manage.py migrate
I'm running on Django 1.7.4.
# base.py
PRIVATE_FOLDER_ROOT = str(PROJECT_DIR.child('web_private'))
# tested: PRIVATE_FOLDER_ROOT = PROJECT_DIR.child('web_private')
# tested: PRIVATE_FOLDER_ROOT = '/var/www/project/project/web_private'
# models.py
from django.conf import settings
#python_2_unicode_compatible
class MessageFile(models.Model):
"""
"""
fs_private_folder = FileSystemStorage(location=settings.PRIVATE_FOLDER_ROOT)
message = models.ForeignKey(Message)
file = models.FileField('file', storage=fs_private_folder, upload_to=get_upload_path_message_file)
when I run
./manage.py migrate <my_app> --settings=myapp.settings.local
I get the following error
NameError: name 'bPath' is not defined
Checking the 0001_initial.py I see that bPath is not imported or defined.
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('file', models.FileField(upload_to=apps.admin_messages.models.get_upload_path_message_file, storage=django.core.files.storage.FileSystemStorage(location=bPath('/var/www/project/project/web_private')), verbose_name=b'file')),
('message', models.ForeignKey(to='admin_messages.Message')),
],
This SO question is linked to mine, but the proposed solution doesn't work.
Thanks,
D
It looks like makemigrations automatically adds a "b" in front of string literals to mark them as byte strings in Python 3.
It may help if you change the cast from str to unicode, ie:
PRIVATE_FOLDER_ROOT = unicode(PROJECT_DIR.child('web_private'))