I have an app (ali
) on my project (website
) and I wanted it to have its own database. The problem is, when I run python manage.py migrate --database=ali
, the command recreates all tables within my ali
database; whereas the expected result would be to have only the ali_search
database.
P.S.: the application seems to be running as expected after I ran some tests. In other words, models from my ali
app are being saved on the ali
DB. Still, having all these empty tables inside my ali
DB is not the correct way to go.
Settings:
# website.settings
...
INSTALLED_APPS = [
'base.apps.BaseConfig',
'ali.apps.AliConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.sites',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sitemaps',
'django_comments',
'mptt',
'tagging',
'zinnia',
]
....
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'website',
'USER': 'website',
'PASSWORD': 'website',
'HOST': 'localhost',
'PORT': '5432',
},
'ali': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'ali',
'USER': 'ali',
'PASSWORD': 'ali',
'HOST': 'localhost',
'PORT': '5432',
}
}
DATABASE_ROUTERS = [
'ali.routers.AliRouter',
]
....
Router:
# ali.routers
class AliRouter:
def db_for_read(self, model, **hints):
if model._meta.app_label == 'ali':
return 'ali'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label == 'ali':
return 'ali'
return None
def allow_relation(self, obj1, obj2, **hints):
if obj1._meta.app_label == 'ali' or \
obj2._meta.app_label == 'ali':
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label == 'ali':
return db == 'ali'
return None
Model:
# ali.models
from django.db import models
class Search(models.Model):
results = models.IntegerField()
This is what I get by querying my ali DB with \dt
:
ali=# \dt
List of relations
Schema | Name | Type | Owner
--------+----------------------------+-------+-------
public | ali_search | table | ali
public | auth_group | table | ali
public | auth_group_permissions | table | ali
public | auth_permission | table | ali
public | auth_user | table | ali
public | auth_user_groups | table | ali
public | auth_user_user_permissions | table | ali
public | django_admin_log | table | ali
public | django_comment_flags | table | ali
public | django_comments | table | ali
public | django_content_type | table | ali
public | django_migrations | table | ali
public | django_session | table | ali
public | django_site | table | ali
public | tagging_tag | table | ali
public | tagging_taggeditem | table | ali
public | zinnia_category | table | ali
public | zinnia_entry | table | ali
public | zinnia_entry_authors | table | ali
public | zinnia_entry_categories | table | ali
public | zinnia_entry_related | table | ali
public | zinnia_entry_sites | table | ali
(22 rows)
But what I would really expect is:
ali=# \dt
List of relations
Schema | Name | Type | Owner
--------+----------------------------+-------+-------
public | ali_search | table | ali
(1 row)
Could it be a problem the fact that the app has the same name as the database (in this case, ali)?
答案 0 :(得分:2)
从None
返回allow_migrate()
意味着路由器对当前操作没有意见。如果所有配置的路由器都没有意见,则默认为允许该操作。您当前的路由器为None
以外的应用返回ali
,因此两个数据库都允许进行这些操作。
要禁止在ali
数据库上迁移其他应用,在这种情况下,您必须显式返回False
,例如:
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label == 'ali':
return db == 'ali'
return db == 'default'
现在,您只需为每个数据库运行migrate
,而不必指定要迁移的应用程序:
$ python manage.py migrate --database=default
$ python manage.py migrate --database=ali
答案 1 :(得分:0)
对我来说,migrate
命令应查看路由以创建表。但似乎并非如此。因此,似乎简单的解决方法是使用migrate
参数调用[app_label]
。像这样:
python manage.py migrate ali --database=ali