python - Django unit test failing for multiple Postgres schemas -



python - Django unit test failing for multiple Postgres schemas -

my postgres db has 3 schemas: default, cedirdata , webdata.

for models pointing different schema default, i'm specifying follows:

class person(models.model): first_name = models.charfield(max_length=200, null=false, blank=false) last_name = models.charfield(max_length=200, null=false, blank=false) class meta: db_table = 'cedirdata\".\"persons'

the application works fine, when seek run tests:

$ ./manage.py test

i following:

file "/home/wbrunetti/.virtualenvs/cedir/local/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 160, in handle executor.migrate(targets, plan, fake=options.get("fake", false)) file "/home/wbrunetti/.virtualenvs/cedir/local/lib/python2.7/site-packages/django/db/migrations/executor.py", line 63, in migrate self.apply_migration(migration, fake=fake) file "/home/wbrunetti/.virtualenvs/cedir/local/lib/python2.7/site-packages/django/db/migrations/executor.py", line 97, in apply_migration migration.apply(project_state, schema_editor) file "/home/wbrunetti/.virtualenvs/cedir/local/lib/python2.7/site-packages/django/db/migrations/migration.py", line 107, in apply operation.database_forwards(self.app_label, schema_editor, project_state, new_state) file "/home/wbrunetti/.virtualenvs/cedir/local/lib/python2.7/site-packages/django/db/migrations/operations/models.py", line 36, in database_forwards schema_editor.create_model(model) file "/home/wbrunetti/.virtualenvs/cedir/local/lib/python2.7/site-packages/django/db/backends/schema.py", line 270, in create_model self.execute(sql, params) file "/home/wbrunetti/.virtualenvs/cedir/local/lib/python2.7/site-packages/django/db/backends/schema.py", line 98, in execute cursor.execute(sql, params) file "/home/wbrunetti/.virtualenvs/cedir/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute homecoming self.cursor.execute(sql, params) file "/home/wbrunetti/.virtualenvs/cedir/local/lib/python2.7/site-packages/django/db/utils.py", line 94, in __exit__ six.reraise(dj_exc_type, dj_exc_value, traceback) file "/home/wbrunetti/.virtualenvs/cedir/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute homecoming self.cursor.execute(sql, params) django.db.utils.programmingerror: schema "cedirdata" not exist

looks might have migrations. since db tables existed created initial migrations , ran --fake:

$ python manage.py makemigrations $ ./manage.py migrate --fake

the test db created default schema only.

i'm using django 1.7 , python 2.7.6.

any thoughts or ideas help.

thanks!

schemas aren't used in many other db engines. specifying schema in models, you've introduced dependency in code postgres.

there 2 routes can take solve problem;

first, add together default search path postgres user. disadvantage of approach schemas can no longer used namespacing, advantage if database ever changes different engine, code function fine. namespacing tables can achieved choosing standard way of naming tables, similar way django default (e.g. appname_classname)

there 2 ways accomplish this. postgres command way is:

alter user (your user) set search_path = "$user",(schema1),(schema2),(schema3),(...)

the django-only way be:

# warning! untested, glanced @ docs , looks right. databases = { 'default': { 'engine': 'django.db.backends.postgresql_psycopg2', # configuration here 'options': { 'options': '-c search_path=schema1,schema2,schema3' } } }

you'll want change:

db_table = 'cedirdata\".\"persons'

to:

db_table = 'persons'

as bonus, can use:

manage.py inspectdb > models.py

which nice feature, way don't have re-create existing database hand.

this solution not help however, if schema namespacing used heavily on database , other applications rely on it. different approach write custom testrunner create schemas in test database. more involved above approach, , can kind of messy. don't recommend doing this, if you're interested seek help.

a less messy, more 'hacky' way override meta when tests beingness run. testrunner.

from django.test.simple import djangotestsuiterunner 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 m in get_models() if '"."' in m._meta.db_table] 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 m in self.schema_models: m._meta.db_table = self.original_db_tables[m]

you'll want define testrunner in settings.py file.

python django postgresql

Comments