Django: Removing unique constraint and creating migration - django

I have created a model and migrated in Django, with a unique key constraint for one of the field. Now am trying to remove the unique constraint and generate another migration file with the new change, but it says "Nothing seems to have changed".
I tried with the command
python manage.py schemamigration --auto
PS: I am using OnetoOne relationship for the field.

Good question. A one to one relationship implies that one record is associated with another record uniquely. Even though the unique constraint is removed(for one to one field) in the code explicitly, it won't be reflected in your DB. So it won't create any migration file.
If you try the same thing for foreign constraint, it will work.

I find the django automigration file generation problematic and incomplete.
Actually I experienced another similar problem with django migration just yesterday.
How I solved it:
delete all migration files from the /migrations folder
do a fresh makemigrations
run python manage.py migrate --fake so django does not try to rebuild..
Hey presto! Working and models updated :D

Related

Initial migrations after cloning repo - "related model cannot be resolved"

I'm working with a few people on an app. I'm doing front end.
Recently, I've messed up migrations. After trying to fix them for a few hours, I've dropped all tables, and cloned the repo again.
Since there are no migrations files, I run manage.py makemigrations (for some reason it does not detect all apps, just one of them, and I have to call makemigrations manually for each of them).
Then, I run manage.py migrate. I get the following error:
Related model 'User.user' cannot be resolved
Since User table has OneToOneField relation to User table. Also, other tables depend on each other as well.
My take on this problem would be commening out all the fields that cause the problem, making migrations, uncommenting them, and making migrations again.
How should I fix it?
Ok, I solved this particular problem:
In User app there was another model, which referred to User. Automatically created migration file had this model before User model, so the script failed, since it could not refer to a model that is yet not created.
I solved this by editing the migration file, swapping the order of creating models - so the second model can refer to the first one.

Django migrations integrity error column contains null values

django.db.utils.IntegrityError: column "required_tem_grid" contains null values
So I mistakenly gave wrong type of value when Django asked me to provide default value for existing rows. Problem is now that I am stuck with this error. I have been burned by this error before too and the only way I could recover was to create another db and running migrations again. Is there any other way? I have tried to revert to previous migration (initial) but this error pops up everywhere. There is no such column in the database that I can see. Is there some place this default value gets cached?
Well I managed to solve it this way: Delete migration files and cached files, remove offending entry from models, delete migration data from django_migrations table for the app, run makemigrations and migrate --fake-initial. I was then able to change models and run migrations.

How to make the initial migration for a DB that diverged from the corresponding models?

Situation: a project I'm working in had a file corruption or something. Models are the latest version, but the SQLite DB had to be rolled back before some columns were added/removed/modified. Migration files are all gone. Trying to create migrations anew results in the new columns being present in the initial migration file, so I can neither migrate for real (due to the table existing) nor fake it (since the columns are missing in the DB).
Given those circumstances, how can I make an initial migration matching the columns currently present in the DB so I can fake it and then make a real second migration to bring the tables in line with the models? The only thing that comes to mind is manually tweaking the models to match the DB schema, making the initial migration, faking it and then restoring the new version of the models, but I'd much prefer having this done automatically.
django inpsectdb to the rescue.
But first, learn how to use git if you had used proper version control, you would not be facing this difficulty now.
First step, add the code to version control.
Delete the existing models files
Use inspectdb to generate a models.py from the tables in the database. This is not perfect, you will have to edit the file manually and you may have to spread it out between different models files manually.
Now delete the contents of the migrations table
do a ./manage.py makemigrations (yourapp)
Do the fake migration you mentioned
replace the generated models.py with your current models.py (a git checkout of that file will do the trick nicely)
do a makemigrations and migrate again.
good luck.

Load fixtures + add Page: IntegrityError (duplicate key value)

I have a migration that loads a fixture for populating the database with a basic site structure (from Loading initial data with Django 1.7 and data migrations
). After that migration ran, my test adds a (custom) NewsPage. THis yields an "IntegrityError at /admin/pages/add/website/newspage/5/
duplicate key value violates unique constraint "wagtailcore_page_pkey"
DETAIL: Key (id)=(3) already exists." The same happens when i add the page through the admin interface.
It's a bit suspicious that the Page with pk=3 is the first one that is created in my fixture. The other two pk's were already created by Wagtail's migrations.
I've read up about fixtures an migrations, and it seems Postgres won't reset the primary key sequences. I'm assuming this is also my problem here.
I found a possible solution in Django: loaddata in migrations errors, but that failed (with "psycopg2.ProgrammingError: syntax error at or near "LINE 1: BEGIN;"). Trying to execute the gist of it, I ran the sqlsequencereset management command (./manage.py sqlsequencereset wagtailcore myapp), but i still get the error, although now for id=4.
Is my assumption correct that Postgres not resetting the primary key sequences is my problem here?
Does anyone know how to reliably fix that from/after a migration loaded fixtures?
Would it maybe be easier / more reliable to create content in Python code?
Edit (same day):
If i don't follow the example in Loading initial data with Django 1.7 and data migrations, but just run the management command, it works:
def load_fixture(fixture_file):
"""Load a fixture."""
commands = StringIO()
call_command('loaddata', fixture_file, stdout=commands)
I don't know what the drawbacks of this more simple approach are.
Edit 2 (also same day):
Ok i do know, the fixtures will be based on the current model state, not the state that the migration is for, so it will likely break if your model changes.
I converted the whole thing to Python code. That works and will likely keep working. Today i learned: don't load fixtures in migrations. (Pity, it would have been a nice shortcut.)

Django won't create a table

I have two different databases in django. Initially, I had a table called cdr in my secondary database. I decided to get rid of the second database and just add the cdr table to the first database.
I deleted references (all of them, I think) to the secondary database in the settings file and throughout my app. I deleted all of the migration files and ran make migrations fresh.
The table that used to be in the secondary database is not created when I run migrate even though it doesn't exist on my postgres database.
I simply cannot for the life of me understand why the makemigrations function will create the migration file for the table when I add it back in to the model definition and I have verified that it is in the migration file. When I run migrate, it tells me there are no migrations to apply.
Why is this so. I have confirmed that I have managed=True. I have confirmed that the model is not on my postgres database by logging into the first database and running \dt.
Why does Django still think that this table still exists such that it is telling me no migrations to apply even though it shows a create command in the migrations file? I even dropped the secondary database to make sure it wasn't somehow being referenced.
I suspect code isn't needed to explain this to me but I will post if needed. I figure I am missing something simple here.
Why does Django still think that this database still exists such that
it is telling me no migrations to apply even though it shows a create
command in the migrations file
Because django maintains a table called django_migrations in your database which lists all the migrations that have been applied. Since you are almost starting afresh, clear out this table and then run the migrations.
If this still doesn't work and still assuming that you are still on a fresh start, it's a simple matter to drop all the tables (or even the database and do the migration again). OTH that you have data you want to save, you need to look at the --fake and --fake-initial options to migrate