[Django]-Django project with a table prefix

4👍

So far I haved solved it like this:

I created a file for each project named table_router.py which i initialized in the defaults apps.

DEFAULT_APPS = [
  'commons.table_router',
  'django.contrib.contenttypes',
  'suit',
  'django.contrib.admin',
  'django.contrib.auth',
  'django.contrib.sessions',
  'django.contrib.messages',
  'django.contrib.staticfiles',
]

Then in this file I have the following:

from django.conf import settings
from django.db.models.signals import class_prepared, pre_init

def add_db_prefix(sender, **kwargs):

    ours = sender._meta.managed
    prefix = getattr(settings, "project1_", None)

    if not ours:
        return

    if prefix and not sender._meta.db_table.startswith(prefix):
        sender._meta.db_table = prefix + sender._meta.db_table

pre_init.connect(add_db_prefix)
class_prepared.connect(add_db_prefix)

What this does is that all Models which are set to be managed by project1 in the Model’s meta info, the prefix project1_ is added to table name Django looks for. Doing so, Django reads auth_ and django_ tables with project1_ prefix, otherwise looks for the table name as I have defined in the Models table_name (tables not managed by project1 and are from project2).

Same file for project2 but with project2 prefix.

1👍

This is an interesting question, so I searched in the source (since the docs only tell, how table names are built, not where this is written)

in django/db/models/options.py I found:

if not self.db_table:
    self.db_table = "%s_%s" % (self.app_label, self.model_name)
    self.db_table = truncate_name(self.db_table, connection.ops.max_name_length())

maybe this can help you…

I assume, that if you write another prefix in there, it will change the default table names. I also assume, you could subclass your own model class from models.Model somewhere in your project, override the contribute_to_class() (that’s where the above lines are from) in it by the changed version with prefix, and then construct all models from your local class instead of models.Model.

But I did not test either…

👤Ilja

Leave a comment