Django migrations RunPython reverse function - django

In the documentation there is a mention of a reverse function in RunPython in django migrations https://docs.djangoproject.com/en/4.0/ref/migration-operations/#runpython
When does the reverse function run?
Is there a specific command to run the reverse function?

Related

How can I make Django create migration files for tables that aren't Django managed?

Background
I've got a Django app that I want to test. The Django app relies on database tables that were created by a different, non-Django app, but in the same database. Every time I try to run a test I get the following error:
django.db.utils.ProgrammingError: relation "mytable" does not exist
I'm thinking that this error is caused by the fact that the table was created manually and there are no migrations.
Question
Is there a way I can tell Django to build migration files based off of a database table that already exists?
There is a tool called inspectdb in Django for this exact scenario.
This should do the trick:
python manage.py inspectdb > models.py
For reference:
https://docs.djangoproject.com/en/3.2/howto/legacy-databases/

Django and materialized views

I have connected my Postgres ddbb with django. With inspectdb I have brought all my tables to models.py.
However, I can't find any command for bringing my materialized views to models.py
I have tryed:
python manage.py inspectdb --database=name_ddbb --include-views
But it only gives me the views, not the materialized views.
How can I add automatically the materialized views to django?
Thanks!
Pass the name of the PostgreSQL materialized view as a parameter to the inspectdb call. In my case, it helped.
Note that you'll probably have to make small changes manually in the resulting model code. In particular, indicate that the id field is the primary key.
You can see the detailed example of the PostgreSQL materialized view in Django in this repository.
Working code pieces illustrating the following:
PostgreSQL materialized view in Django.
EagerLoadingMixin in Django REST framework serializer classes to
solve the N+1 queries problem.
Usage of the most generic viewsets.ModelViewSet to build views in
Django REST framework fast and easy.
Advanced PostgreSQL SQL Query with several Common Table Expressions
and JSON functions.
Django post_save and m2m_changed signals.

Can you stop Django automatically reverting a manual Migration?

I have a Model file which has a change which isn't being picked up by DJango makemigrations.
I created a manual migration following this answer, but if we run makemigrations afterwards Django creates a new auto migration reverting our manual changes.
Is there a way to manually make a migration and tell DJango to ignore relevant parts of the code when generating future migrations?
After making changes to the models and creating a custom migration for them e.g. using RunPython or RunSQL you can use the state_operations argument to reflect the changed models' state in your custom Python or SQL operations.

How to control the order of created fields during a migration

I add custom fields in a model that require to be created in the order they are defined in the model. In the file created by the Django migration, this order is not respected.
Is there a way to tell Django makemigrations the order of operations ?
I use Django 1.8 and MySQL 5.7.
There aren't any options that you can pass to the makemigrations command to specify the order.
However, you can reorder the operations in the migrations file that is created.

Django - Why doesn't syncdb respect the database router?

I have set up a database router to direct different apps and different models to different databases using the db_for_read and db_for_write router methods.
That works very well, except that ./manage.py syncdb does't respect those router settings.
When I syncdb my models, all of them are created in the default database.
The database router only provides an allow_syncdb method, but no sync_to method. Is there a way to tell the syncdb command where to create the new tables?
Note: I can't use the --database feature, as sometimes some of the model apps go to a different database than the rest of the app.
When you write your router make sure you've written the allow_syncdb() method. It takes both a database and a model. When you run manage.py syncdb you're essentially setting the --database=default. If you don't want your models to sync to the default database then your allow_syncdb() method should return False for the condition that db==default and model._meta.app_label==myapp.
You'll need to run syncdb with the --database=your_other_db option to get myapp into that db. But make sure in that case that allow_syncdb() returns True only for the case that db==your_other_db and model._meta.app_label==myapp.
Does that make sense? Basically you have to run the manage.py syncdb method twice, once for each database. You cannot run it only once and have it update both databases.