Django migrations circular dependency what is the best practice? - python

I would like to know the best practice to handle circular dependency when migrating apps.
Our CRM has two Apps with several model fields depending on each other.
We need to reconstruct the database everyday and this lead us to delete all our existing migration files and create new ones everyday.
In our code the foreign keys are referenced with :
model_name = models.ForeignKey('app.model', ...)
So no issues at runtime.
But at night, when we recreate and apply the migrations, we made a migrate script that basically swaps the foreign keys as IntegerField to prevent CircularDependencyError and reswaps them after the depencies are solved.
Is there a better way to do this ?

Related

Should I avoid using models in django migrations?

I am working on an existing Django project that contains migration code like:
someFluffyModel.objects.all().delete()
or
someModel = SomeModel(....)
someModel.save()
Now wherever there is such code and newer migrations change the schema that reflect the current version of the model, there is an issue in applying migrations from scratch.
As I understand the reason is that the model used in the migration doesn't reflect the model used in the migration at that point in time. As I have found fixtures can help in loading data but how about deletion?
Is the preferred way to manually delete data from the database?
Sorry forgot to answer my own old question it's been years now but just in case anybody is curious in your migrations you should always be using historical models. The reason is that you get the model at a point in time(reconstructed incrementally base on schema migrations).
def forwards_func(apps, schema_editor):
# We get the model from the versioned app registry;
# if we directly import it, it'll be the wrong version
Country = apps.get_model("myapp", "Country")
This way if you try to re-run your migrations at some point in the future with model schema x'' old migrations will be run using x' and x depending on their dependencies.
Avoid importing models to your migrations directly at any cost.
It is always important to be able to rer-run you migrations since that allows you to migrate forwards backwards between your environments roll back faulty deployments and above all run your tests. If you are doing it wrong your tests will fail at some point when you'll get to schema x' and you'll have to follow the correct approach mentioned above to fix them.
Thanks to #Daniel Roseman for giving me some pointers that day.

Django Rebuild all migrations

I am building an app in Django and it uses a live/in-use database.
Basically since the apps development the SQL Database has undergone some structure changes and it is causing issues with Django, Django will try to apply migrations to the database that already exist. For example:
In the Django app I marked the email column as unique which was fine based on the development database. However the main database now always has a table change that marks the email column as unique. Django is fighting this unique key with the one that already exists.
So is it possible to clear all Django migrations and have it make migrations again compared to the more up to date SQL database structure?
If your models are very out of sync with your database, the easiest option is probably to rebuild your models from scratch using inspectdb.
If your models are pretty close to the database already, the first step is to make sure that your models match the database exactly. You can use sqldiff from django-extensions for this.
Once your Django models match your database, follow this answer to re-create migrations based on the existing database schema.

How to approach Django project starting with database schema?

Every Django tutorial/book I've seen approaches Django projects from what I am going to characterize as an ad-hoc database design method. A project ends-up being a bunch of little apps, each with it's own models, view, etc.
I am trying to locate a resource that covers how to structure a Django project when you do, in fact, start with a traditional DB design process.
For example, let's say that this is the starting point:
And a document describing it:
LEAD Database Guide
How does one approach this so that the various Django apps access a single "global" (bad word) db model that covers the entire schema rather than a bunch of models spread across a bunch of apps?
Are there any resources (books, pdf's, tutorials) that cover this approach rather than the piece-meal approach most commonly seen?
A corollary to this question might be: Is there a, perhaps automated, way to go from an SQL (or MySQL Workbench) schema definition to the equivalent Django ORM?
You can use the inspectdb command to generate models.py from database:
http://docs.djangoproject.com/en/dev/ref/django-admin/#inspectdb
Then, you can treat the models as a single app, and add more features/tables into new apps in the future.

running into migration conflicts with south

I am working with some other developers on a website (using Django) and as it is a new site and the database schema is constantly changing. We are using South for schema migration but are running into the issue where each of us have our own branch checked out and are working on our own separate part of the project. When the code is merged back in very often there have been multiple migrations generated for the same model (there might be three migrations with id 003 for model A).
It seems like South is pretty good about managing conflicts when they relate to different models:
http://south.readthedocs.org/en/latest/tutorial/part5.html#team-workflow
But when dealing with the same model it gets a little messy manually creating the merged migration.
I was wondering if there was any better way of doing this or a better tool than South.
One idea I have is for no one to check in the migration files and just check in the model changes directly to git. That way every person would just run their own migrations and won't have to worry about conflicts. Not sure if that is a good practice...
I am curious how other people are managing these situations.
Thanks:)
From the South documentation:
Make sure your team know who is working on what, so they don’t write migrations that affect the same parts of the DB at the same time.
So that's the thing you shouldn't do: don't create migrations that affect the same model unless you're sure you're able to merge them later into the main development trunk. A tool can't figure out what the right database schema needs to be when two developers modify the same field of a model.
In that case you'll need to manually fix migrations and get the model fields in order. This could mean migrating back and constructing a new migration before merging the branch with the trunk.

What migration order does South follow across different apps?

I've recently begun using South for migrations in my Django project. All was going well until recently when I ran into a peculiar issue.
I have two apps in my project, say, App-A and App-B. A model in App-A has a foreign key to a model in App-B. When I've been trying to build my system, I ran syndb which created all the auth_ and the south_ tables. Then I ran migrate which threw up errors. When it tried creating the model from App-A, which referenced a model from App-B, the model App-B wasn't migrated/created as yet and therefore the error.
In order to resolve this, I had to manually migrate App-B first and then App-A. Am i doing something wrong here? How is South supposed to know the migration order across apps?
Thanks.
This explained it https://south.readthedocs.io/en/latest/dependencies.html.
Migrations for apps are nice ‘n all, but when you start writing a
large project, with a lot of apps, you realise you have foreign key
relationships between apps and working out what order migrations would
need to be applied in for each app is just painful.
Luckily, we also had this problem, so South has a dependency system.
Inside a migration, you can declare that it depends on having another
app having run a certain migration first; for example, if my app
“forum” depends on the “accounts” app having created its user profile
table, we can do:
# forum/migrations/0002_post.py class Migration:
depends_on = (
("accounts", "0003_add_user_profile"),
)
def forwards(self):
Then, if you try and migrate to or beyond 0002_post in the forum app, it will first make sure accounts is migrated at least
up to 0003_add_user_profile, and if not will migrate it for you.
Dependencies also work in reverse; South knows not to undo that
0003_add_user_profile migration until it has undone the 0002_post
migration.
You can have multiple dependencies, and all sorts of wacky structures;
there are, however, two rules:
No circular dependencies (two or more migrations depending on each
other) No upwards dependencies in the same app (so you can’t make
0002_post in the forum app depend on 0003_room in the same app, either
directly or through a dependency chain.
South migrates apps in the order they appear in the INSTALLED_APPS tuple in settings.py. So just make sure App-B comes before App-A in your settings.py, and it should work :)

Categories

Resources