[Django] #23347: Add --dry-run to migrate

20 views
Skip to first unread message

Django

unread,
Aug 22, 2014, 4:27:22 PM8/22/14
to django-...@googlegroups.com
#23347: Add --dry-run to migrate
-----------------------------+----------------------
Reporter: Naddiseo | Owner: nobody
Type: New feature | Status: new
Component: Migrations | Version: 1.7-rc-3
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+----------------------
In a similar vein to https://code.djangoproject.com/ticket/23263, I would
like to propose that a "--dry-run" or "--check" be added to the `migrate`
command. Basically, I want to be able to run through the migrations
without it making database changes, so that I can see if I've broken
something, especially if I'm writing a migration with a `RunPython`.

Another way I can see this working, is if sqlmigrate could also output all
the sql that was issued, including those issued by `RunPython`, so that if
I had the following migration [#migration '[0]'] it would output something
similar to [#output '[1]']


[=#migration [0]] Migration:
{{{#!python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

def update_contenttypes(apps, schema_editor):
ContentType = apps.get_models('contenttypes', 'ContentType')
ContentType.objects.get(pk = 1)

class Migration(migrations.Migration):
dependencies = [
('everdeal', '0001_initial'),
]

operations = [
migrations.RunPython(update_contenttypes)
]

}}}


[=#output [1]] Output:

{{{#!bash
BEGIN;
--
-- MIGRATION NOW PERFORMS OPERATION THAT CANNOT BE WRITTEN AS SQL:
-- Raw Python operation
SELECT * FROM contenttypes_contenttype WHERE id=1;
--

ROLLBACK;


}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/23347>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Aug 26, 2014, 10:23:51 AM8/26/14
to django-...@googlegroups.com
#23347: Add --dry-run to migrate
-----------------------------+--------------------------------------
Reporter: Naddiseo | Owner: nobody
Type: New feature | Status: closed
Component: Migrations | Version: 1.7-rc-3
Severity: Normal | Resolution: needsinfo
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------------------------
Changes (by timgraham):

* status: new => closed
* needs_better_patch: => 0
* resolution: => needsinfo
* needs_tests: => 0
* needs_docs: => 0


Comment:

I don't see a way to implement what you propose. I don't think there is a
way to output SQL for arbitrary `RunPython` without actually running it as
queries may dependent on each other (for example manipulating models in a
loop of `MyModel.objects.all()`). If you have an idea, please provide it
(or a patch).

--
Ticket URL: <https://code.djangoproject.com/ticket/23347#comment:1>

Django

unread,
Aug 26, 2014, 11:37:35 AM8/26/14
to django-...@googlegroups.com
#23347: Add --dry-run to migrate
-----------------------------+--------------------------------------
Reporter: Naddiseo | Owner: nobody
Type: New feature | Status: closed
Component: Migrations | Version: 1.7-rc-3
Severity: Normal | Resolution: needsinfo
Keywords: | Triage Stage: Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------------------------

Comment (by Naddiseo):

Maybe my understanding of databases is wrong, but couldn't you create a
savepoint at the beginning, do all the migrations - including the
`RunPython` - then issue a rollback at the end?

--
Ticket URL: <https://code.djangoproject.com/ticket/23347#comment:2>

Django

unread,
Aug 26, 2014, 12:36:05 PM8/26/14
to django-...@googlegroups.com
#23347: Add --dry-run to migrate
-----------------------------+--------------------------------------
Reporter: Naddiseo | Owner: nobody
Type: New feature | Status: closed
Component: Migrations | Version: 1.7-rc-3
Severity: Normal | Resolution: needsinfo
Keywords: | Triage Stage: Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------------------------

Comment (by charettes):

@Naddiseo unfortunately not all supported backends support transactional
DDL which might end up committing the active transaction silently.

We can't assume only SQL will be executed by `RunPython` given the
provided `schema_editor`.

--
Ticket URL: <https://code.djangoproject.com/ticket/23347#comment:3>

Django

unread,
Aug 26, 2014, 12:37:30 PM8/26/14
to django-...@googlegroups.com
#23347: Add --dry-run to migrate
-----------------------------+--------------------------------------
Reporter: Naddiseo | Owner: nobody
Type: New feature | Status: closed
Component: Migrations | Version: 1.7-rc-3
Severity: Normal | Resolution: needsinfo
Keywords: | Triage Stage: Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------------------------

Comment (by timgraham):

(Was about to make a similar comment as @charettes.)

As for alternatives: I don't quite understand your use case "so I can see
if I've broken something." Migrations are executed when you run tests so
you could test it there. Also the migration is executed in a transaction,
so if it breaks somewhere in the middle, any changes should be rolledback.
Maybe you could elaborate why either of these options aren't sufficient.

--
Ticket URL: <https://code.djangoproject.com/ticket/23347#comment:4>

Django

unread,
Aug 27, 2014, 12:13:12 AM8/27/14
to django-...@googlegroups.com
#23347: Add --dry-run to migrate
-----------------------------+--------------------------------------
Reporter: Naddiseo | Owner: nobody
Type: New feature | Status: closed
Component: Migrations | Version: 1.7-rc-3
Severity: Normal | Resolution: needsinfo
Keywords: | Triage Stage: Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------------------------

Comment (by Naddiseo):

> Also the migration is executed in a transaction, so if it breaks
somewhere in the middle, any changes should be rolledback.

Unless it's a backend that doesn't support transactions?

My "use case" is that I like to do incremental testing while I'm
developing - and by testing, I don't mean test cases, I mean running the
code to see if it doesn't have runtime errors - so if I'm writing a data
migration, I may right a small section of it, then run the migration to
see if what I have works, then move on to the next part, but I don't want
the database to be changed when I run it again. Currently, I can work
around this by raising an Exception to force a rollback; providing a "dry-
run" option would, for me, be a preferable approach, and providing the
would-be committed sql would aid in any kind of debugging where looking at
the sql is necessary.

I guess if not all of the backends support transactions, then I guess this
can't really be done (cleanly anyway), and this ticket can be resolved.
Thanks for your time.

--
Ticket URL: <https://code.djangoproject.com/ticket/23347#comment:5>

Django

unread,
Mar 12, 2015, 11:46:59 PM3/12/15
to django-...@googlegroups.com
#23347: Add --dry-run to migrate
-----------------------------+--------------------------------------
Reporter: Naddiseo | Owner: nobody
Type: New feature | Status: closed
Component: Migrations | Version: 1.7-rc-3
Severity: Normal | Resolution: needsinfo
Keywords: | Triage Stage: Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------------------------

Comment (by Suor):

This would be use full even without `RunPython` support. I used this
feature a lot in south.

--
Ticket URL: <https://code.djangoproject.com/ticket/23347#comment:6>

Django

unread,
Mar 28, 2015, 3:35:26 PM3/28/15
to django-...@googlegroups.com
#23347: Add --dry-run to migrate
-----------------------------+--------------------------------------
Reporter: Naddiseo | Owner: nobody
Type: New feature | Status: closed
Component: Migrations | Version: 1.7-rc-3
Severity: Normal | Resolution: needsinfo
Keywords: | Triage Stage: Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------------------------

Comment (by MarkusH):

If you want to see the particular SQL code generated for a migration you
can use [https://docs.djangoproject.com/en/1.7/ref/django-admin
/#sqlmigrate-app-label-migrationname sqlmigrate]

--
Ticket URL: <https://code.djangoproject.com/ticket/23347#comment:7>

Django

unread,
Mar 7, 2018, 4:04:11 PM3/7/18
to django-...@googlegroups.com
#23347: Add --dry-run to migrate
-------------------------------+--------------------------------------
Reporter: Richard Eames | Owner: nobody
Type: New feature | Status: closed
Component: Migrations | Version: 1.7-rc-3
Severity: Normal | Resolution: needsinfo
Keywords: | Triage Stage: Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------

Comment (by Craig de Stigter):

I've re-requested a similar thing in #29198

--
Ticket URL: <https://code.djangoproject.com/ticket/23347#comment:8>

Django

unread,
Oct 3, 2022, 11:00:25 AM10/3/22
to django-...@googlegroups.com
#23347: Add --dry-run to migrate
-------------------------------+--------------------------------------
Reporter: Richard Eames | Owner: nobody
Type: New feature | Status: closed
Component: Migrations | Version: 1.7-rc-3
Severity: Normal | Resolution: needsinfo
Keywords: | Triage Stage: Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------

Comment (by Michael):

The plan option does not help me, it just says `Raw Python operation` for
my custom migration.

I just added a error at the end of the migration, so that it rolls back,
now can run it as many times as desired, then remove the error when
confident:

{{{
from django.db import migrations


def forwards_func(apps, schema_editor):
Meeting = apps.get_model("meetings", "Meeting")
db_alias = schema_editor.connection.alias
for meeting in Meeting.objects.using(db_alias).all():
if meeting.meeting_utc is None:
print(meeting.meeting_date, meeting.meeting_time)
raise ValueError("Don't commit!") # <----------------

class Migration(migrations.Migration):
dependencies = [
('meetings', '0004_meeting_meeting_utc_meeting_time_is_null'),
]

operations = [
migrations.RunPython(forwards_func),
]

}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/23347#comment:9>

Reply all
Reply to author
Forward
0 new messages