W dniu sobota, 5 listopada 2016 17:30:15 UTC+1 użytkownik Andrew Godwin 
napisał:
>
> Hello! I have opinions about this :)
>  
>
>> Possible solution (or "how I'd build it today if there was no existing 
>> code in Django core"):
>>
>> a. Make migrations part of the project and not individual apps. This 
>> takes care of problem 3 above.
>>
>
> It also means it's impossible for apps to ship migrations and define how 
> to upgrade from version to version. I realise that (c) below is part of a 
> proposed solution to this, but how do you propose to match up what's 
> already been run in the database without having names match (and then you 
> just have app migrations by another name)?
>

I would actually insist on keeping the names intact. It means that adding 
an external dependency could inject a migration with a date from the 
previous year but I think that's not a problem as it's guaranteed not to 
conflict with any other migrations.


>> b. Prefix individual migration files with a UTC timestamp 
>> (20161105151023_add_foo) to provide a strict sorting order. This removes 
>> the depsolving requirement and takes care of 1 and 2. By eliminating those 
>> it makes 4 kind of obsolete as squashing migrations would become pointless.
>>
>
> Unfortunately this does not help all the time as computers' clocks aren't 
> necessarily right or in sync, so it would merely be an approximation and 
> you'd still get the occasional clash.
>

You only need your own migrations to be ordered so you can safely assume 
the previous one to be applied before the one you're writing at the moment. 
For two unrelated changes the order pretty much does not matter.
 

> c. Have reusable apps provide migration templates that Django then copies 
>> to my project when "makemigrations" is run.
>>
>
> Would these be lined up with their own timestamp in the single serial 
> migration timeline? Would you have to make sure any of these templates from 
> any app update was copied across and put in the order before you used the 
> new columns?
>

I'd say use proper timestamps. This way two apps can depend on each other 
and the migrations will still get run in proper order.
 

> d. Maintain a separate directory for each database connection.
>>
>
> This I think might be a good idea, though I'd like to see a more 
> generalised idea of "migration sets" and you then then say which alias uses 
> which set (so you can share sets among more than one connection)
>

Agreed.
 

> e. Execute all migrations in alphabetical order (which means by timestamp 
>> first). When an unapplied migration is followed by an applied one, ask 
>> whether to attempt to just apply it or if the user wants to first unapply 
>> migrations that came after it. To me this would work better than 6.
>>
>
> This is basically what South used to do, and it worked reasonably well in 
> either being successful or exploding enough that people noticed. Given that 
> you're proposing per-project migrations, however, people are going to run 
> into this almost constantly, as they will clash significantly more than 
> per-app ones.
>

South was not perfect but I'd say the current solution is not better, it's 
just different. Some of my projects use a lot of long-running feature 
branches so I have an application where every other migration is a merge 
migration with accepted default values. We do try to make migrations 
backwards-compatible where needed but I don't think it's a common scenario 
to add conflicting changes on two feature branches. Most of our conflicts 
can be described as department A added a field they needed while department 
B added a data migration to fix a denormalized field.
 

> Of course we do have migration support in core and it's not compatible 
>> with most of the above list. Any ideas? I think serializing the dependency 
>> solver state and reusing it between runs could be a pretty low hanging 
>> fruit (like "npm shrinkwrap" or yarn's lock file).
>>
>
> I think not only could the dependency solver state be serialised but that 
> it would be a replacement for the datetimes-on-filename proposal in that 
> you could easily pull out a previously-serialised order from disk and then 
> work out what the new ones do.
>
> I am generally not keen on the idea of per-project migrations, though - it 
> makes what's in the database a property of the project, not the app, and 
> that's not how Django has worked traditionally. I think an effort to get a 
> more reliable, exposed global ordering of those individual app migrations 
> would go a long way towards the end goal without having to have migration 
> templates, upgrade instructions, and way more collisions between branches.
>

I do believe that the database is my property and I'd much rather see the 
project code hold reign over its structure. Some problems simply cannot be 
solved by submitting an upstream patch (project-specific or 
backend-specific indexes come to mind).
 

> At the end of the day, though, there's a reason I made the schema editing 
> separate from the migration runners - you can re-use all the nasty work in 
> the schema editing interface and just replace the other part. This huge 
> change is the sort of thing I'd want to see working and proven before we 
> considered changing core, preferably as a third-party app, but of course 
> I'd like to talk through potential smaller changes first, rather than 
> throwing out the entire system.
>

Thank you for your comments. Another topic I'd like to touch is making 
migrations easier to apply without touching all of Django's machinery. In 
many environments (dockerized apps, multi-server auto-scaled groups) we 
simply can't run migrations as part of the deployment step. What you then 
have to do is run some of the migrations (all added fields have to be 
nullable etc.), make sure no regressions happened and then start deploying 
code that depends on the introduced changes. Once you're done you can run 
the second part of migrations that add constraints. Making migrations part 
of the project would make this process easier and in theory could be done 
out-of-tree (assuming migrations themselves don't import stuff from outside 
of Django).

I'm sure Carl could share some of Heroku's stories about migrating 
databases in large deployments.

Cheers,

-- 
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/44bb4b38-dce0-481f-93df-5e92c6f06187%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to