7👍
Schemas aren’t used in many other DB engines. By specifying a schema in your models, you’ve introduced a dependency in your code for postgres.
There are two routes you can take to solve your problem;
First, you could add a default search path to your postgres user. The disadvantage of this approach is that schemas can no longer be used for namespacing, but the advantage is that if your database ever changes to a different engine, your code will function just fine. Namespacing your tables can be achieved by choosing some standard way of naming your tables, similar to the way that Django does it by default (e.g. appName_className)
There are two ways to achieve this. The postgres command to do it this way is:
ALTER USER (your user) SET search_path = "$user",(schema1),(schema2),(schema3),(...)
The django-only way to do it would be:
# Warning! This is untested, I just glanced at the docs and it looks right.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
# some configuration here
'OPTIONS': {
'options': '-c search_path=schema1,schema2,schema3'
}
}
}
You’ll also want to change:
db_table = 'cedirData\".\"persons'
to:
db_table = 'persons'
As a bonus, you can now use:
manage.py inspectdb > models.py
which is a nice feature, that way you don’t have to copy your existing database by hand.
This solution will not help you however, if schema namespacing was used heavily on your database and other applications rely on it. A different approach would be to write a custom testrunner to create those schemas in your test database. This is somewhat more involved than the above approach, and can be kind of messy. I don’t really recommend doing this, but if you’re interested I could try to help.
A less messy, but more ‘hacky’ way would be to simply override meta when tests are being run. This would also be a testrunner.
from django.test.simple import DjangoTestSuiteRunner
from django.db.models.loading import get_models
class SchemaModelTestRunner(DjangoTestSuiteRunner):
"""Docstring"""
def setup_test_environment(self, *args, **kwargs):
self.original_db_tables = {}
self.schema_models = [m for m in get_models()
if '"."' in m._meta.db_table]
for m in self.schema_models:
schema, table = m._meta.db_table.split('"."')
self.original_db_tables[m] = m._meta.db_table
m._meta.db_table = 'schema_'+schema+'_table_'+table
super(SchemaModelTestRunner, self).setup_test_environment(*args,
**kwargs)
def teardown_test_environment(self, *args, **kwargs):
super(SchemaModelTestRunner, self).teardown_test_environment(*args,
**kwargs)
# reset models
for m in self.schema_models:
m._meta.db_table = self.original_db_tables[m]
You’ll also want to define this as a testrunner in your settings.py file.