Django Column 'id' cannot be null - django

I am having a weird problem with my mysql database and django.
I created an app with a model imported from an existing database with inspectdb. It was working fine until yesterday I removed the django automatically created tables (django_, auth_, site_*). I did that because it was preventing my model to validate when I added my app in the installed apps.
Now today I tried inserting a new record in my database and I get the following error :
Django Version: 1.3
Exception Type: IntegrityError
Exception Value: (1048, "Column 'asset_id' cannot be null")
The field is a primary key and it's supposed to be auto_increment so I don't give a value to it when I create a new record.
Can someone point me what's going on here ?
EDIT : I partly figured out the problem : somehow all my auto_increment proprities were removed from my database. How did that happen ?

Check your generated models, and ensure that the "auto_increment" columns correspond with fields marked with the primary_key=True option.

May be you need to save your object model, before obtain id property.

Related

Verify database integrity using Django

There is a complex app with the back-end powered by Django. It contains many-to-one many-to-many and https://django-polymorphic.readthedocs.io/en/stable/.
Using Django migration for updating database models.
Problem
A very complex migration for the existing database fails. There Foreign Key constraint related problems similar to:
ERROR: insert or update on table "foo" violates foreign key constraint "D286496390ec910156ccc566ec44e73f"
DETAIL: Key (bar_id)=(123) is not present in table "bar".
So in other words there is a record which references a non-existing record in the database.
Question
Is it possible to somehow use Django to iterate over each object in the database and validate it contains no "broken" records (referencing non-existent records)?
Short Answer
Yes, you can use django shell ./manage.py shell to iterate your model and check.
Long Anser
$ ./manage.py shell
>>> from your_app.models import MyCoolModel
>>> for item in MyCoolModel.objects.all():
... if item.foreign_field < 0: # do the control here
... # fix the non valid.
... ...

unique_together does not replace primary key

In my Django app, I want to insert a record with a composite primary key. Apparently this should be possible by making use of "unique_together". I'm quite sure this code was working in the past, but for some reason it does not seem to be working now. This code used to run on a Linux VM, and now I'm hosting it in Google App Engine. However I don't see how this can be the cause for this error.
class TermsAndConditionsDocument(models.Model):
organization = models.ForeignKey(Organization, on_delete=models.CASCADE, verbose_name=_("Organization"))
language = models.CharField(_('Language'),choices=LANGUAGE_CHOICES, max_length=5, help_text=_("The language of the content."))
content = models.TextField()
class Meta:
unique_together = ('organization', 'language')
The error:
IntegrityError at /transactions/settings/terms_and_conditions
null value in column "id" violates not-null constraint
DETAIL: Failing row contains (null, nl-BE, <p>B</p>, 10).
According to what I've read, using "unique_together" should cause Django to not need or include an ID as primary key. I checked the database, and the ID field DOES exist. I do not understand where the database constraint and the ID field are still coming from?
Apparently, as pointed out in the comments, a primary key "id" field is always added, even if you don't need it. It's supposed to get out of your way, so you don't even notice its existence. In my case, it required me to give it a value when I created a new record, which is not how things are supposed to work.
A while back I migrated this database from one Postgres database to another Postgres database. I used an SQL dump and load method for this. Some sequences seem to have been lost during that migration.
Because there are no sequences, some fields now lacked autoincrement capabilities, explaining the IntegrityError on insertion.
In order to fix this, I did the following:
1) Export the current data:
manage.py dumpdata > data.json
2) Drop your database and create a new empty one.
3) Run database migrations:
manage.py migrate
4) Load the data again, excluding some default data already recreated by Django.
manage.py loaddata --exclude auth.permission --exclude contenttypes data.json
This procedure seems to have recreated the sequences while also keeping the data.
The unique_together only creates a DB constraint (https://docs.djangoproject.com/en/2.2/ref/models/options/#unique-together).
You could create a custom primary key with the option primary_key https://docs.djangoproject.com/en/2.2/ref/models/fields/#django.db.models.Field.primary_key but you could only do that for one field.
But I suggest to just keep the auto increment id field, this works better with Django.
For the error are you saving a model? or doing a raw import?

django doesn't detect migrations

I am using modeltranslation(https://github.com/deschler/django-modeltranslation) and django-eav(https://github.com/mvpdev/django-eav) apps. I want to translate django-eav app model's field description. As it is documented, i created class:
class AttributeTranslationOptions(TranslationOptions):
fields = ('description', )
and registered it: translator.register(Attribute, AttributeTranslationOptions). Basically this creates additional fields for languages that my project supports, in my case it's 4. It should be: description_en, description_ru and so on.. This works fine with my other models, but when i try to translate Attribute class, it says (1054, "Unknown column 'eav_attribute.description_en' in 'field list'"). Then i try to migrate, but it doesn't detect changes. Tried south schemamigration app_name --auto, also doesn't work.
How can i solve this?
Thanks
EDITED:
Tried python manage.py schemamigration eav --initial. Now it finds these fields:
+ Added field description_ru on eav.Attribute
+ Added field description_lv on eav.Attribute
+ Added field description_en on eav.Attribute
BUT, then another error occurs: FATAL ERROR - The following SQL query failed: CREATE TABLE eav_enumvalue (id integer AUTO_INCREMENT NOT NULL PRIMARY KEY, value varchar(50) NOT NULL UNIQUE, icon varchar(300) NULL)
The error was: (1050, "Table 'eav_enumvalue' already exists")

Devise trying to save password attribute to database

Running Rails 4.2 and devise 3.4.1
I've added "devise :database_authenticatable", to a User model, and everything works exactly as expected .... except, when the record is saved or created I get this error:
Mysql2::Error: Unknown column 'password' in 'field list': UPDATE users SET password = NULL, .....
The devise attribute/method 'password' is clearly being added to the sql but is not a column within the table.
I'm stumped ... Any ideas?
Please check your migration file if there is a encrypted_password field. Next check the structure of users table in database. There should be encrypted_password column too. You can also override devise views and see what happen inside form and try to debug it with console help.

South and Django - error on migration of unique=True

I have tried to change field's property - from unique=False to unique=True
and I'm getting the following error:
django.db.utils.IntegrityError: could not create unique index "xxx_fieldname_key"
DETAIL: Key (fieldname)=() is duplicated.
Any idea how to solve that?
Looks like the field you're trying to make unique already has records with duplicate value on fieldname. Check in your database if it's the case. Post your model code and full error message if not.