When I run my test dealing with my Customer
model, I get the following error:
DatabaseError: (1146, \"Table \'test_mcif2.customer\' doesn\'t exi
The solutions presented by tarequeh worked for me after overriding DATABASE_ROUTERS.
I am using routers in order to prevent writes on the legacy database. In order to get around this I created a test_settings file with the following contents:
from settings import *
DEBUG = True
TEST_RUNNER = 'legacy.utils.ManagedModelTestRunner'
DATABASE_ROUTERS = []
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(HERE, 'test.db'),
},
}
Then when running tests:
python manage.py test [app_name] --settings=test_settings
Since you're using a legacy database, you are probably not adding the app name to INSTALLED_APPS. If an app is not included in INSTALLED_APPS, the tables for the apps' models will not get created on syncdb. This works for you in production since you already have a table, but not in test environment.
You can adopt any of the following:
The supermonkeypatch way: Take out app_name from Customer class Meta, put the model in a models.py file inside a python module name mcif, and add mcif to INSTALLED_APPS - just for the sake of testing
The nicer way: Extend DjangoTestSuiteRunner and override setup_test_environment to call super and then create your legacy table manually in the test DB.
The nicest way: Put your model in properly named app module. Remove app_name from model Meta but add managed=False docs. Include app name in INSTALLED_APPS. Now django will not create table for that model. Then use this nice snippet the Caktus group folks have compiled to run your tests.
Cheers!
Edit - How to use the overridden DjangoTestSuiteRunner
You will need at least Django 1.2 for this.
Copy the code from here. Put it in utils.py inside the mcif app.
Add/edit the following in settings.py:
TEST_RUNNER = 'mcif.utils.ManagedModelTestRunner'
Now when you run tests, all unmanaged tables will be treated as managed table only for the duration of the test. So the tables will be created prior to running tests.
Notice this part of the code, thats where the magic happens.
self.unmanaged_models = [m for m in get_models() if not m._meta.managed]
for m in self.unmanaged_models:
m._meta.managed = True
2nd Edit: Possible Gotchas
Make sure of the following:
3rd Edit: Debugging Inside mcif.utils.ManagedModelTestRunner replace setup_test_environment function with the following and let me know if the output of your test changes:
def setup_test_environment(self, *args, **kwargs):
print "Loading ManagedModelTestRunner"
from django.db.models.loading import get_models
self.unmanaged_models = [m for m in get_models()
if not m._meta.managed]
for m in self.unmanaged_models:
print "Modifying model %s to be managed for testing" % m
m._meta.managed = True
super(ManagedModelTestRunner, self).setup_test_environment(*args, **kwargs)
There's not enough info above to answer your first question. However, once you get that issue resolved you'll probably want to install django-extensions for the following reason: It has an incredibly useful sqldiff
command that will inform you if there's a mismatch between the legacy database and your application model.