Skip to content

Instantly share code, notes, and snippets.

@asfaltboy
Last active March 30, 2022 23:52
Show Gist options
  • Select an option

  • Save asfaltboy/b3e6f9b5d95af8ba2cc46f2ba6eae5e2 to your computer and use it in GitHub Desktop.

Select an option

Save asfaltboy/b3e6f9b5d95af8ba2cc46f2ba6eae5e2 to your computer and use it in GitHub Desktop.

Revisions

  1. asfaltboy revised this gist Jun 9, 2019. 1 changed file with 10 additions and 3 deletions.
    13 changes: 10 additions & 3 deletions conftest.py
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,7 @@
    # based on https://gist.github.com/blueyed/4fb0a807104551f103e6
    # and on https://gist.github.com/TauPan/aec52e398d7288cb5a62895916182a9f (gistspection!)

    from django.core.management import call_command
    from django.db import connection
    from django.db.migrations.executor import MigrationExecutor

    @@ -18,23 +19,29 @@ def migration(request, transactional_db):
    The methods return `old_apps` and `new_apps` respectively; these can
    be used to initiate the ORM models as in the migrations themselves.
    For example:
    def test_foo_set_to_bar(migration):
    old_apps = migration.before(['my_app', '0001_inital'])
    old_apps = migration.before([('my_app', '0001_inital')])
    Foo = old_apps.get_model('my_app', 'foo')
    Foo.objects.create(bar=False)
    assert Foo.objects.count() == 1
    assert Foo.objects.filter(bar=False).count() == Foo.objects.count()
    # executing migration
    new_apps = migration.apply(['my_app', '0002_set_foo_bar'])
    new_apps = migration.apply([('my_app', '0002_set_foo_bar')])
    Foo = new_apps.get_model('my_app', 'foo')
    assert Foo.objects.filter(bar=False).count() == 0
    assert Foo.objects.filter(bar=True).count() == Foo.objects.count()
    Based on: https://gist.github.com/blueyed/4fb0a807104551f103e6
    """
    class Migrator(object):
    def before(self, targets):
    """ Specify app and starting migration names as in:
    before(['app', '0001_before']) => app/migrations/0001_before.py
    before([('app', '0001_before')]) => app/migrations/0001_before.py
    """
    self.executor = MigrationExecutor(connection)
    # prepare state of db to before the migration ("migrate_from" state)
  2. asfaltboy revised this gist May 14, 2018. 1 changed file with 4 additions and 8 deletions.
    12 changes: 4 additions & 8 deletions conftest.py
    Original file line number Diff line number Diff line change
    @@ -9,7 +9,7 @@

    @pytest.fixture()
    def migration(request, transactional_db):
    # snagged from https://gist.github.com/TauPan/aec52e398d7288cb5a62895916182a9f
    # see https://gist.github.com/asfaltboy/b3e6f9b5d95af8ba2cc46f2ba6eae5e2
    """
    This fixture returns a helper object to test Django data migrations.
    The fixture returns an object with two methods;
    @@ -36,19 +36,15 @@ def before(self, targets):
    """ Specify app and starting migration names as in:
    before(['app', '0001_before']) => app/migrations/0001_before.py
    """
    self.migrate_from = targets
    self.executor = MigrationExecutor(connection)
    self._old_apps = self.executor.migrate(self.migrate_from).apps
    # prepare state of db to before the migration ("migrate_from" state)
    # self._old_apps = self.executor.loader.project_state(self.migrate_from).apps
    self._old_apps = self.executor.migrate(targets).apps
    return self._old_apps

    def apply(self, targets):
    """ Migrate forwards to the "migrate_to" migration """
    self.migrate_to = [(app, migration) for app, migration in targets]
    """ Migrate forwards to the "targets" migration """
    self.executor.loader.build_graph() # reload.
    self._new_apps = self.executor.migrate(self.migrate_to).apps
    # self._new_apps = self.executor.loader.project_state(self.migrate_to).apps
    self._new_apps = self.executor.migrate(targets).apps
    return self._new_apps

    # ensure to migrate forward migrated apps all the way after test
  3. asfaltboy revised this gist May 14, 2018. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions conftest.py
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,5 @@
    # based on https://gist.github.com/blueyed/4fb0a807104551f103e6
    # and on https://gist.github.com/TauPan/aec52e398d7288cb5a62895916182a9f (gistspection!)

    from django.db import connection
    from django.db.migrations.executor import MigrationExecutor
  4. asfaltboy revised this gist May 14, 2018. 1 changed file with 16 additions and 26 deletions.
    42 changes: 16 additions & 26 deletions conftest.py
    Original file line number Diff line number Diff line change
    @@ -7,62 +7,52 @@


    @pytest.fixture()
    def migration(transactional_db):
    def migration(request, transactional_db):
    # snagged from https://gist.github.com/TauPan/aec52e398d7288cb5a62895916182a9f
    """
    This fixture returns a helper object to test Django data migrations.
    The fixture returns an object with two methods;
    - `before` to initialize db to the state before the migration under test
    - `after` to execute the migration and bring db to the state after the migration
    The methods return `old_apps` and `new_apps` respectively; these can
    be used to initiate the ORM models as in the migrations themselves.
    For example:
    def test_foo_set_to_bar(migration):
    old_apps = migration.before('my_app', '0001_inital')
    old_apps = migration.before(['my_app', '0001_inital'])
    Foo = old_apps.get_model('my_app', 'foo')
    Foo.objects.create(bar=False)
    assert Foo.objects.count() == 1
    assert Foo.objects.filter(bar=False).count() == Foo.objects.count()
    # executing migration
    new_apps = migration.apply('my_app', '0002_set_foo_bar')
    new_apps = migration.apply(['my_app', '0002_set_foo_bar'])
    Foo = new_apps.get_model('my_app', 'foo')
    assert Foo.objects.filter(bar=False).count() == 0
    assert Foo.objects.filter(bar=True).count() == Foo.objects.count()
    Based on: https://gist.github.com/blueyed/4fb0a807104551f103e6
    """
    class Migrator(object):
    def before(self, app, migrate_from, ):
    """ Specify app and starting migration name as in:
    before('app', '0001_before') => app/migrations/0001_before.py
    def before(self, targets):
    """ Specify app and starting migration names as in:
    before(['app', '0001_before']) => app/migrations/0001_before.py
    """
    self.app = app
    self.migrate_from = [(app, migrate_from)]
    self.migrate_from = targets
    self.executor = MigrationExecutor(connection)
    self.executor.migrate(self.migrate_from)
    self._old_apps = self.executor.migrate(self.migrate_from).apps
    # prepare state of db to before the migration ("migrate_from" state)
    self._old_apps = self.executor.loader.project_state(self.migrate_from).apps
    # self._old_apps = self.executor.loader.project_state(self.migrate_from).apps
    return self._old_apps

    def apply(self, app, migrate_to):
    def apply(self, targets):
    """ Migrate forwards to the "migrate_to" migration """
    self.migrate_to = [(app, migrate_to)]
    self.migrate_to = [(app, migration) for app, migration in targets]
    self.executor.loader.build_graph() # reload.
    self.executor.migrate(self.migrate_to)
    self._new_apps = self.executor.loader.project_state(self.migrate_to).apps
    self._new_apps = self.executor.migrate(self.migrate_to).apps
    # self._new_apps = self.executor.loader.project_state(self.migrate_to).apps
    return self._new_apps

    # ensure to migrate forward migrated apps all the way after test
    def migrate_to_end():
    for _ in range(len(apps)):
    app = apps.pop()
    # migrator.apply(app, '__latest__')
    call_command('migrate', app, verbosity=0)
    call_command('migrate', verbosity=0)
    request.addfinalizer(migrate_to_end)

    return Migrator()
    return Migrator()
  5. asfaltboy revised this gist Feb 20, 2017. 1 changed file with 8 additions and 0 deletions.
    8 changes: 8 additions & 0 deletions conftest.py
    Original file line number Diff line number Diff line change
    @@ -57,4 +57,12 @@ def apply(self, app, migrate_to):
    self._new_apps = self.executor.loader.project_state(self.migrate_to).apps
    return self._new_apps

    # ensure to migrate forward migrated apps all the way after test
    def migrate_to_end():
    for _ in range(len(apps)):
    app = apps.pop()
    # migrator.apply(app, '__latest__')
    call_command('migrate', app, verbosity=0)
    request.addfinalizer(migrate_to_end)

    return Migrator()
  6. asfaltboy revised this gist Feb 20, 2017. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions conftest.py
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    # based on https://gist.github.com/blueyed/4fb0a807104551f103e6

    from django.db import connection
    from django.db.migrations.executor import MigrationExecutor

  7. asfaltboy created this gist Jan 27, 2017.
    58 changes: 58 additions & 0 deletions conftest.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,58 @@
    from django.db import connection
    from django.db.migrations.executor import MigrationExecutor

    import pytest


    @pytest.fixture()
    def migration(transactional_db):
    """
    This fixture returns a helper object to test Django data migrations.
    The fixture returns an object with two methods;
    - `before` to initialize db to the state before the migration under test
    - `after` to execute the migration and bring db to the state after the migration
    The methods return `old_apps` and `new_apps` respectively; these can
    be used to initiate the ORM models as in the migrations themselves.
    For example:
    def test_foo_set_to_bar(migration):
    old_apps = migration.before('my_app', '0001_inital')
    Foo = old_apps.get_model('my_app', 'foo')
    Foo.objects.create(bar=False)
    assert Foo.objects.count() == 1
    assert Foo.objects.filter(bar=False).count() == Foo.objects.count()
    # executing migration
    new_apps = migration.apply('my_app', '0002_set_foo_bar')
    Foo = new_apps.get_model('my_app', 'foo')
    assert Foo.objects.filter(bar=False).count() == 0
    assert Foo.objects.filter(bar=True).count() == Foo.objects.count()
    Based on: https://gist.github.com/blueyed/4fb0a807104551f103e6
    """
    class Migrator(object):
    def before(self, app, migrate_from, ):
    """ Specify app and starting migration name as in:
    before('app', '0001_before') => app/migrations/0001_before.py
    """
    self.app = app
    self.migrate_from = [(app, migrate_from)]
    self.executor = MigrationExecutor(connection)
    self.executor.migrate(self.migrate_from)
    # prepare state of db to before the migration ("migrate_from" state)
    self._old_apps = self.executor.loader.project_state(self.migrate_from).apps
    return self._old_apps

    def apply(self, app, migrate_to):
    """ Migrate forwards to the "migrate_to" migration """
    self.migrate_to = [(app, migrate_to)]
    self.executor.loader.build_graph() # reload.
    self.executor.migrate(self.migrate_to)
    self._new_apps = self.executor.loader.project_state(self.migrate_to).apps
    return self._new_apps

    return Migrator()