I'm working on adding Django 2.0 support to the django-pagetree library. During automated testing, using an sqlite in-memory database, I'm getting a bunch of errors like this:
File "/home/nnyby/src/django-pagetree/pagetree/tests/test_models.py", line 638, in setUp
'children': [],
File "/home/nnyby/src/django-pagetree/pagetree/models.py", line 586, in add_child_section_from_dict
...
File "/home/nnyby/src/django-pagetree/venv/lib/python3.5/site-packages/django/db/backends/base/base.py", line 239, in _commit
return self.connection.commit()
django.db.utils.IntegrityError: FOREIGN KEY constraint failed
This is noted in the Django 2.0 release notes: https://docs.djangoproject.com/en/2.0/releases/2.0/#foreign-key-constraints-are-now-enabled-on-sqlite
From that description, which I don't fully understand, this shouldn't apply for test databases that aren't persistent, right? Wouldn't my sqlite test db get created with the appropriate options when using Django 2.0?
The app settings I'm using for testing are here: https://github.com/ccnmtl/django-pagetree/blob/master/runtests.py
The documentation says two things:
If you have ForeignKey constraints they are now enforced at the database level. So make sure you're not violating a foreign key constraint. That's the most likely cause for your issue, although that would mean you'd have seen these issues with other databases. Look for patterns like this in your code:
# in pagetree/models.py, line 810
#classmethod
def create_from_dict(cls, d):
return cls.objects.create() # what happens to d by the way?
This will definitely fail with a ForeignKey constraint error since a PageBlock must have section, so you can't call create without first assigning it.
If you circumvent the foreign key constraint by performing an atomic transaction (for example) to defer committing the foreign key, your Foreign Key needs to be INITIALLY DEFERRED. Indeed, your test db should already have that since it's rebuilt every time.
I met a different situation with the same error. The problem was that I used the same Model name and field name
Incorrect code:
class Column(models.Model):
...
class ColumnToDepartment(models.Model):
column = models.ForeignKey(Column, on_delete=models.CASCADE)
Solution:
class Column(models.Model):
...
class ColumnToDepartment(models.Model):
referring_column = models.ForeignKey(Column, on_delete=models.CASCADE)
Do you have add on_delete to your FOREIGN KEY? On Django 2.0 this argument is required.
You could see also:
https://docs.djangoproject.com/en/2.0/ref/models/fields/#django.db.models.ForeignKey.on_delete
https://docs.djangoproject.com/en/2.0/howto/upgrade-version/
https://docs.djangoproject.com/en/2.0/topics/db/examples/many_to_one/
https://docs.djangoproject.com/en/2.0/ref/models/fields/#django.db.models.ForeignKey
In my case, I found that the ForeignKey object that my model refers to does not exist.
Therefore, I change the referenced FK object to the existing object.
A reason could be you miscalculated what happens when you delete an item from the db that is linked with a foreign key to something else, elsewhere.
p.e. what happens when you delete an author that has active books?
I don't meant to enter into the logic of the application, but consider for example to cascade the deletion of the elements linked to that key.
Here is an example, in this case we are dealing with "post" attribute for each "user"
user = models.ForeignKey(User, related_name='posts', on_delete=models.CASCADE)
Here's a careful explanation, Django 4.0:
https://docs.djangoproject.com/en/4.0/ref/models/fields/
I just had this error: sqlite3.IntegrityError: FOREIGN KEY constraint failed on my Django project. Turns out I deleted the migrations folder somewhere along the line so it didn't pick up my model changes when I ran python manage.py makemigrations. Just make sure you still have a migrations folder with migrations in.
One more thing to check, in my case it was related to my fixtures files.
Regenerating them after migration to Django3 solved the issue I had while testing my app.
./manage.py dumpdata app.Model1 app.Model2 --indent=4 > ./app/fixtures/file.json
When I have trouble with migrations or tables, I do it and it very often helps:
Comment your trouble strings;
Do python3 manage.py makemigrations and python3 manage.py migrate;
Then u must do python3 manage.py migrate --fake;
Uncomment your strings and do it again python3 manage.py makemigrations and python3 manage.py migrate.
I hope it is useful for u
My problem was solved after doing the migration, because I have altered the foreign key and then didn't apply the migrations.
Specifically, at first I have the following piece of code in models:
class TeacherRequest(models.Model):
requester = models.ForeignKey(
Profile,
on_delete=models.CASCADE,
related_name="teacher_request",
)
class RequestStatus(models.TextChoices):
PENDING = '1', _('pending')
APPROVED = '2', _('approved')
REJECTED = '3', _('rejected')
status = models.CharField(
choices=RequestStatus.choices,
max_length=1,
default=RequestStatus.PENDING,
)
Then I have changed the foreign key from Profile to User:
class TeacherRequest(models.Model):
requester = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name="teacher_request",
)
class RequestStatus(models.TextChoices):
PENDING = '1', _('pending')
APPROVED = '2', _('approved')
REJECTED = '3', _('rejected')
status = models.CharField(
choices=RequestStatus.choices,
max_length=1,
default=RequestStatus.PENDING,
)
Solution
python manage.py makemigrations
python manage.py migrate
Most probably the cause of the error is the lacking of matching Foreignkey elements in your model and the one your trying to save(update using that foreignkey).
Make sure that the foreignkey constraints(value) are present in both your and the new data
I met a different situation with the same error.
The problem was that i had my on_delete attributes set to DO_NOTHING, which ended up violating foreign key constraints.
Setting it to SET_NULL fixed it for me.
Related
I am using Django 2.1.2
I am having 2 Models Items and Quotation.
class Item(models.Model):
name = models.CharField(max_length=200)
def __str__(self):
return self.name
class Quotation(models.Model):
company = models.ForeignKey('Company', on_delete=models.CASCADE)
unit_rate = models.CharField(max_length=200)
item = models.ManyToManyField(Item)
def __str__(self):
return self.company.company_name
Now when I am adding Item it is working correctly.
But when I try to add quotation in Admin Panel, it gives me null value in column "item_id" violates not-null constraint
I am new to Django. It would be great if someone can point what I am missing.
It looks as if you might have changed Quotation.item from a ForeignKey or OneToOneField to a ManyToManyField field.
After making this change, you have to run manage.py makemigrations and then manage.py migrate to create and then run the necessary database migrations. Note that any existing data in the Quotation.item_id column will be deleted unless you write migrations to copy the data to the many-to-many field.
This happened with me too recently while working on a client project. Guess what, the client developer forgot to make migrations after modifying a model in Django.
This error usually occurs because of DB. You can check the table details in DB to make sure that the field you're passing null value to is actually nullable or not.
eg. in Postgres - \d table_name;
How I solved it?
python manage.py makemigrations
python manage.py migrate
I' ve the following simplified model structure:
#common/models.py
class CLDate(models.Model):
active = models.BooleanField(default=True)
last_modified = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
#br/models.py
class Dokument(CLDate):
user = models.ForeignKey(User)
class Entity(CLDate):
dokument = models.ForeignKey(Dokument)
. Both class inherits from CLDate, and i' ve a OneToMany relation between them. When i try to migrate, i got the following error:
python manage.py makemigrations
SystemCheckError: System check identified some issues:
ERRORS:
br.Entity.dokument: (models.E006) The field 'dokument' clashes with the
field 'dokument' from model 'common.cldate'.
I can' t really get why is this structure a problem for Django hence the Entity is a totally different object than the Dokument. Could anyone explain me why, and how could i solve it with this structure? So both should inherit from CLDate and there should be this kind of relation between the 2 models from the br application.
I also tried to delete all the migration files, and solve it that way, but the same. Runserver gives also this error.
Django: 1.11.2
Python: 3.4.2
Debian: 8.8
.
Thanks.
If i rename the dokument property name in the Entity model, it works fine.
I' m also almost pretty the same layout was working previously (in previous Django versions).
Since you are using multi-table inheritance, Django creates an implicit one-to-one field from Dokument to CLDate. The reverse relation dokument from CLDate to Dokument is clashing with your Entity.dokument field.
If you don't want to rename your Entity.dokument field, then your other option is to explicitly define the parent link field from Dokument to CLDate and set related_name.
class Dokument(CLDate):
cl_date = models.OneToOneField(CLDate, parent_link=True, related_name='related_dokument')
user = models.ForeignKey(User)
So I have seen that a lot of these kinds of questions have popped up (few answered) and none in a Django aspect that I saw. I am confused why I am getting the error, I am guessing i am missing something on my field decorator or what not in my model definition. Here are the two models... (one abbreviated). I thought I did everything right with unique and primary key set to true in the one table that the foreign key gives reference to but upon migrate I get this error:
django.db.utils.ProgrammingError: there is no unique constraint matching given keys for referenced table "swsite_zoneentity"
Edit up dated the code ...
class ZoneEntity(models.Model):
zone_number = models.CharField(max_length=100, primary_key=True)
mpoly = models.PolygonField() #this should grow and shrink for the most representative one...
objects = models.GeoManager()
created_at=models.DateField(auto_now_add=True)
updated_at=models.DateField(auto_now=True)
class CesiumEntity(models.Model):
be_number = models.CharField(max_length=100) #the number assigned to a foot print to distinguish
#zone_id = models.CharField(max_length=100, null=True, blank=True)
zone_id = models.ForeignKey('ZoneEntity', null=True, blank=True)
To solve this, needed to add the unique constraint on the postgres table id myself.
psql <your-database-name>
ALTER TABLE swsite_zoneentity ADD CONSTRAINT zone_unique_id UNIQUE(id);
Like this answer
This problem appears most times because you copied or created your database from a dump and somewhere the unique constraint on your primary key column(as well as other constraints got lost.
Solution:
Open your DB with pg4admin or any client, Databases>your_database>schema>public>tables>your_table right-click
on the table name,
Choose Properties
Select columns tabs
switch primary key on your pk column
save/exit
run migration again
Codejoy,
When you define a primarykey, it is automatically set as unique.. So, just go by:
class ZoneEntity(models.Model):
zone_number = models.CharField(max_length=100, primary_key=True)
....
class CesiumEntity(models.Model):
...
zone_id = models.ForeignKey('ZoneEntity', null=True, blank=True)
...
This will automatically bind the PK of ZoneEntity with zone_id!
If the field you are trying to make the relation IS NOT the primary key, then you can add unique=True and to_field='foo'
- python manage.py. makemigration
s
Migrations for 'module1':
0002_auto_20170214_1503.py:
- Create model CesiumEntity
- Create model ZoneEntity
- Add field zone_id to cesiumentity
- python manage.py migrate
Operations to perform:
Synchronize unmigrated apps: staticfiles, messages
Apply all migrations: admin, contenttypes, module1, auth, sessions
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Installing custom SQL...
Running migrations:
Rendering model states... DONE
Applying module1.0002_auto_20170214_1503... OK
I too had same issue while migrating DB from SQLite to PostgreSQL 14.4, even when referenced Foreign key had primary_key=True set.
Deleting the old migrations, solved my issue.
How to replace default primary key in Django model with custom primary key field?
I have a model with no primary key defined at first since django automatically adds an id field by default as primary field.
#models.py
from django.db import models
class Event(models.Model):
title = models.CharField(max_length=50, unique=True)
description = models.CharField(max_length=150)
I added some objects into it from django shell.
>>e = Event('meeting', 'Contents about meeting')
>>e.save()
>>e = Event('party', 'Contents about party')
>>e.save()
Then I require to add custom character field as primary into this model.
class Event(models.Model):
event-id = models.CharField(max_length=50, primary_key=True)
...
Running makemigrations:
$ python manage.py makemigrations
You are trying to add a non-nullable field 'event-id' to event without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows)
2) Quit, and let me add a default in models.py
Select an option: 1
Please enter the default value now, as valid Python
The datetime and `django.utils.timezone modules` are available, so you can do e.g. timezone.now()
>>> 'meetings'
Migrations for 'blog':
0002_auto_20141201_0301.py:
- Remove field id from event
- Add field event-id to event
But while running migrate it threw an error:
.virtualenvs/env/local/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 485, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: UNIQUE constraint failed: blog_event__new.event-id
In my experience (using Django 1.8.* here), I've seen similar situations when trying to update the PK field for models that already exist, have a Foreign Key relationship to another model, and have associated data in the back-end table.
You didn't specify if this model is being used in a FK relation, but it seems this is the case.
In this case, the error message you're getting is because the data that already exists needs to be made consistent with the changes you're requesting --i.e. a new field will be the PK. This implies that the current PK must be dropped for django to 'replace' them. (Django only supports a single PK field per model, as per docs[1].)
Providing a default value that matches currently existing data in the related table should work.
For example:
class Organization(models.Model):
# assume former PK field no longer here; name is the new PK
name = models.CharField(primary_key=True)
class Product(models.Model):
name = models.CharField(primary_key=True)
organization = models.ForeignKey(Organization)
If you're updating the Organization model and products already exist, then existing product rows must be updated to refer to a valid Organization PK value. During the migration, you'd want to choose one of the existing Organization PKs (e.g. 'R&D') to update the existing products.
[1] https://docs.djangoproject.com/en/1.8/topics/db/models/#automatic-primary-key-fields
Django has already established an auto incrementing integer id as primary key in your backend as and when u made the previous model.
When u were trying to run the new model , An attempt was made to recreate a new primary key column that failed.
Another reason is,When u made the field,Django was expecting a unique value be explicitly defined for each new row which it couldn't found,hence the reason.
As told in previous answer you can re-create the migration and then try doing it again.It should work.. cheers :-)
The problem is that you made the field unique, then attempted to use the same value for all the rows in the table. I'm not sure if there's a way to programmatically provide the key, but you could do the following:
Delete the migration
Remove the primary_key attribute from the field
Make a new migration
Apply it
Fill in the value for all your rows
Add the primary_key attribute to the field
Make a new migration
Apply it
It's bruteforce-ish, but should work well enough.
Best of luck!
I'm using userena and after adding the following line to my models.py
zipcode = models.IntegerField(_('zipcode'),
max_length=5)
I get the following error after I hit the submit button on th signup form:
IntegrityError at /accounts/signup/
NOT NULL constraint failed: accounts_myprofile.zipcode
My question is what does this error mean, and is this related to Userena?
You must create a migration, where you will specify default value for a new field, since you don't want it to be null. If null is not required, simply add null=True and create and run migration.
coldmind's answer is correct but lacks details.
The NOT NULL constraint failed occurs when something tries to set None to the zipcode property, while it has not been explicitly allowed.
It usually happens when:
Your field has Null=False by default, so that the value in the database cannot be None (i.e. undefined) when the object is created and saved in the database (this happens after a objects_set.create() call or setting the .zipcode property and doing a .save() call).
For instance, if somewhere in your code an assignment results in:
model.zipcode = None
This error is raised.
When creating or updating the database, Django is constrained to find a default value to fill the field, because Null=False by default. It does not find any because you haven't defined any. So this error can not only happen during code execution but also when creating the database?
Note that the same error would be returned if you define default=None, or if your default value with an incorrect type, for instance default='00000' instead of 00000 for your field (maybe can there be an automatic conversion between char and integers, but I would advise against relying on it. Besides, explicit is better than implicit). Most likely an error would also be raised if the default value violates the max_length property, e.g. 123456
So you'll have to define the field by one of the following:
models.IntegerField(_('zipcode'), max_length=5, Null=True,
blank=True)
models.IntegerField(_('zipcode'), max_length=5, Null=False,
blank=True, default=00000)
models.IntegerField(_('zipcode'), max_length=5, blank=True,
default=00000)
and then make a migration (python3 manage.py makemigration <app_name>) and then migrate (python3 manage.py migrate).
For safety you can also delete the last failed migration files in <app_name>/migrations/, there are usually named after this pattern:
<NUMBER>_auto_<DATE>_<HOUR>.py
Finally, if you don't set Null=True, make sure that mode.zipcode = None is never done anywhere.
If the zipcode field is not a required field then add null=True and blank=True, then run makemigrations and migrate command to successfully reflect the changes in the database.
In Django Null=True means Null Values are accepted. But Some Filed having Django that Blank=True are not satisfied for put Blank fields.
DateTimeField
ForeignKey
These two fields are used and if you want to put Blank I recommend adding NULL=TRUE
Since you added a new property to the model, you must first delete the database. Then manage.py migrations then manage.py migrate.