Django Database_Router类位于“默认”数据库上

时间:2019-02-08 15:25:19

标签: python django postgresql

我遇到了Django模型数据库路由问题。我已经做了相当多的研究,但是没有运气。

首先,了解与该问题相关的应用程序的信息。

我选择使用数据库路由来分离应用程序中的模型。该应用程序适用于n个公司(例如foo1),并且它们都有自己的django应用程序,包括几乎相同的models.py文件。

模式路由由用户在db连接中完成。

-“默认”数据库连接的目的是处理auth和contenttype随附的模型。这是与foo0相同的架构,因为此连接适用于处理django auth AbstractUser扩展的应用程序。

我的settings.py看起来像这样。

DATABASE_ROUTERS = ['django_project.database_router.django_projectDatabaseRouter']

DATABASES = {
'default': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': 'postgres',
    'USER' : 'foo0_user@django_projectdatabase',
    'PASSWORD' : 'x',
    'HOST' : 'x',
    'PORT' : '5432',
},
'foo0': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': 'postgres',
    'USER' : 'foo0_user@django_projectdatabase',
    'PASSWORD' : 'x',
    'HOST' : 'x',
    'PORT' : '5432',
},
'foo1':{
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': 'postgres',
    'USER' : 'foo1_user@django_projectdatabase',
    'PASSWORD' : 'x',
    'HOST' : 'x',
    'PORT' : '5432',
},
'foo2':{
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': 'postgres',
    'USER' : 'foo2_user@django_projectdatabase',
    'PASSWORD' : 'x',
    'HOST' : 'x',
    'PORT' : '5432',
}
}

这是相应的数据库路由器类(出于调试目的进行了调整)。

class django_projectDatabaseRouter:
def db_for_read(self, model, **hints):
    print('reading from database ' + model._meta.app_label)
    return model._meta.app_label

def db_for_write(self, model, **hints):
    print('writing to database ' + model._meta.app_label)
    return model._meta.app_label

def allow_relation(self, obj1, obj2, **hints):
    #if obj1._meta.app_label == obj2._meta.app_label:
    #    return True
    #elif obj1._meta.app_label in ['auth','contenttypes','sessions'] or obj1._meta.app_label in ['auth','contenttypes','sessions']:
    #    return True
    #return None
    return None

def allow_migrate(self, db, app_label, model_name=None, **hints):
    if app_label == 'foo0':
        print(app_label + ', ' + str(db=='foo0'))
        return db == 'foo0'
    elif app_label == 'foo1':
        print(app_label + ', DB=' + db + ', model='+model_name)
        db='foo1'
        return db == 'foo1'
    elif app_label == 'foo2':
        print('app_label='app_label + ', ' + str(db=='foo2'))
        return db == 'foo2'
    elif app_label in ['auth','contenttypes','sessions'] and db == 'default':
        print('--------auth---------')
        print(db + ', ' + app_label + ', ' + model_name)
        return db=='default'
    return db == app_label

foo0模型都具有相应的数据库名称

class Field_Picture(models.Model):
field1_id = models.ForeignKey(Field, on_delete=models.SET_NULL, null=True)
picture_id = models.ForeignKey(Picture, on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True)

class Meta:
    app_label = 'foo1'

运行 python manage.py makemigrations 创建正确的迁移,但是当我运行 manage.py migration foo1 0001 我得到了这个输出。

Running migrations:
Applying foo1.0001_initial...
app_label=foo1, DB=default, model=some_random_model
app_label=foo1, DB=default, model=some_random_model
....
 OK

如您所见,模型已链接到“默认”数据库,而不是所需的“ foo1”。我认为问题出在以下事实:路由器从未在auth以外的模型上调用db_for_write函数。

总结我的问题:

数据库路由器将忽略模型元数据的app_label,仅通过allow_migrate()函数传递db ='default'的迁移。

如果有人遇到类似问题或对该领域有知识,我将不胜感激。

0 个答案:

没有答案