Hi Arthur.

BTW: RunPython() is another thing, which can break your migrations, and 
should not be used (especially not by Django internally), because it relies 
on the application layer.

How else can you do a data migration? There is no 
> `migrations.InsertIntoTable`, 
>

You're right. That's why "Insert" should be (in my opinion) introduced. 
Together with "migrations.Delete".

The problem is that data migration based on app layer (python objects, ie. 
Models and Managers here) will cause troubles after some time (when app is 
changing).
In the other words - you cannot rely on your app layer when doing database 
changes. You should never do that, especially for projects requiring LTS.

RunPython() should be used only when you cannot do anything else. In such 
case you must accept all consequences. I'm not against RunPython(), but 
against doing data migrations using it.

The problem with hypothetical "Insert" operation is with mapping field 
types. Insert cannot use Models directly (app layer is changing over a 
time), but should "know" how to map arguments (python types, values) to a 
database literals. It can be achieved by introducing field mapping for a 
every insert or per migration file (something like "model freeze", but only 
for used fields). 

Also Insert should not accept variables calculated in the app layer (within 
a migration) - it should contain only plain/direct data. But using Python 
as a language for migrations, will be hard to avoid such possibility. This 
is important, because database management should not rely on app layer. 
Using variables (i.e. from settings) would result in inconsistent data 
changes between different environments.

the only other way currently would be to run a `migrations.RunSql` query 
> which may look different based on the database used.
>

RunSQL is not the solution for db agnostic operations. It may be only used 
within a project, because db engine used changes rarely (due to the nature 
and importance of the data and relational databases, and systems dependent 
on the db). 
But RunSQL is a handful operation, because SQL is a natural language for db 
management. I'm doing many raw sqls in migrations.
 

> Two things are wrong:
>
>    - automatic creation of content types
>
> Why is it wrong to automatically create a content type? 
>

Maybe "automatic" is not a proper word. They should be created 
automatically, but should be applied "at the right time".
 

> Content type is an opt-in feature since you can remove it from 
> `INSTALLED_APPS`.
>

I know, but it is required by contrib.auth. I saw no project depending on 
something else, so CT is optional.. but theoretically ;)
  

>
>    - creation of content types after running migrations
>
> That’s the only real problem for me. Maybe using a signal for 
> `migrations.CreateModel` (e.g. post_create_model), instead of using 
> `post_migrate` would fix it, but there may be other scenarios I’m not 
> thinking about.
>

Because signals are related to the app layer and  mixing app and db layers 
together is generally wrong (sorry for wording, please read as "not so 
good"), changing one signal to another is not a good solution.

Before I wrote about the issue, I was doing diagnosis and I was thinking 
about the issue for a while. So I think that the best place for applying 
data changes is a migration.
Django can detect model changes (adding and removals of models, too), so it 
can generate series of inserts or deletes in the right place, to run them *at 
the right time*.

Or if `django.contrib.contenttypes` is only added later on to 
> `INSTALLED_APPS`?


After adding contrib.contenttypes, Django should check existence of 
django_content_type table. If exists, Django should only check for data 
changes and generate series of inserts/deletes. If not, Django should 
generate inserts for all models. If CT is removed later, Django should 
remove all CT data .


CT opt-in should be connected to a signal related to the creation of 
migration files (Autodetector?), not to a signal related to their 
execution. I.e. pre/post_autodection signals should be introduced.


Kind Regards,

Marcin

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/af22034d-3983-4b19-87b2-256adc1cb11a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to