-
-
Save nealtodd/2869341f38f5b1eeb86d to your computer and use it in GitHub Desktop.
# If your test settings file doesn't import any other settings file | |
# then you can use the function directly: | |
def prevent_tests_migrate(db): | |
import django | |
from django.db import connections | |
from django.db.migrations.executor import MigrationExecutor | |
django.setup() | |
ma = MigrationExecutor(connections[db]).loader.migrated_apps | |
return dict(zip(ma, ['{a}.notmigrations'.format(a=a) for a in ma])) | |
MIGRATION_MODULES = prevent_tests_migrate('default') | |
# If your test settings file imports another settings file (typically | |
# your base settings file, then the function won't work as the settings | |
# won't be fully in scope by the time setup() is called. Depending on | |
# you settings layout you'll an error like: | |
# "ImproperlyConfigured: The SECRET_KEY setting must not be empty." | |
# or ""Apps aren't loaded yet", or "RuntimeError: populate() isn't reentrant" | |
# | |
# Instead, simply use the function in the Django shell to generate the | |
# dictionary and hardcode it to MIGRATION_MODULES in the test settings. | |
# Since Django is already set up in the shell the function can just be: | |
def prevent_tests_migrate(db): | |
from django.db import connections | |
from django.db.migrations.executor import MigrationExecutor | |
ma = MigrationExecutor(connections[db]).loader.migrated_apps | |
return dict(zip(ma, ['{a}.notmigrations'.format(a=a) for a in ma])) | |
# You'll need to manually update MIGRATION_MODULES if you add new apps | |
# with migrations and want them skipped as well. | |
# | |
# Also, if you suddenly come across an error like this when Django starts up: | |
# "Migration foo.0001_initial dependencies reference nonexistent | |
# parent node (u'bar', u'0001_initial')" | |
# then it probably means you've added an app (maybe 3rd party) that has a | |
# dependency on one of the apps in MIGRATION_MODULES that you've skipped | |
# (e.g. a dependency on the contenttypes app). To fix, simply add the new | |
# app to MIGRATION_MODULES. | |
This is awesome. I was bogged down by the unit tests trying to run the migrations first to create a test db. It's working greatly.
Thanks!
Thanks!
Placing those lines in settings.py gives me
django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.
Trying to figure this out.
@martync - that'll probably be because you need to define SECRET_KEY before calling prevent_tests_migrate in settings.py because the django.setup() call needs it.
The code I come up with : https://gist.github.com/NotSqrt/5f3c76cd15e40ef62d09
No strange error, because no django.setup()
Was just adding a comment as to why using this function directly sometimes might not work (i.e. when the test settings file imports another settings file) and saw the code from @NotSqrt.
Now that's an elegant solution!
I focused too much on replicating how Django generates its default MIGRATION_MODULES, with a fake module name, rather than faking the method calls on the dictionary.
Thanks @NotSqrt, I'll adopt your approach. (Should be fine as long as none creates an app called notmigrations ;-)
Pretends migrated apps aren't migrated by giving them a fake migration module (so syncdb behaviour is used instead). Mimics the old SOUTH_TESTS_MIGRATE = False behaviour in South.
MIGRATION_MODULES could be a hard-coded dictionary of known apps. This function simply does it dynamically.
This is intended for 1.7 only, pending the --keepdb flag in Django 1.8. It's also only intended for faster running of a single test, not a whole testsuite run (which, correctly, should use migrations as Andrew Goodwin intended it to).