Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在Django中只使用一个表使用多个数据库;django_移民”;_Python_Django_Django Models - Fatal编程技术网

Python 在Django中只使用一个表使用多个数据库;django_移民”;

Python 在Django中只使用一个表使用多个数据库;django_移民”;,python,django,django-models,Python,Django,Django Models,对于Django中的项目,我必须使用两个数据库:default和remote。我创建了routers.py,一切正常 需要在远程数据库上创建一个表,我创建了迁移,运行它,然后创建了表django_migrations。我只希望在默认数据库中有一个表django_migrations Operations to perform: Apply all migrations: admin, auth, contenttypes, sessions Running migrations: App

对于Django中的项目,我必须使用两个数据库:defaultremote。我创建了
routers.py
,一切正常

需要在远程数据库上创建一个表,我创建了迁移,运行它,然后创建了表
django_migrations
。我只希望在默认数据库中有一个表
django_migrations

Operations to perform: Apply all migrations: admin, auth, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying auth.0010_alter_group_name_max_length... OK Applying auth.0011_update_proxy_permissions... OK Applying sessions.0001_initial... OK
routers.py
的相关部分如下:

class MyRouter(object):
     # ...
     def allow_migrate(self, db, app_label, model_name=None, **hints):
         if app_label == 'my_app':
             return db == 'remote'
         return None
我按如下方式运行迁移:

python manage.py migrate my_app --database=remote
python manage.py migrate --database=default
python manage.py migrate --database=remote
现在当我这样做的时候:

python manage.py runserver
我得到以下警告:

您有1个未应用的迁移。您的项目可能无法正常工作,除非您为应用程序(my_应用程序)应用迁移。
运行“python manage.py migrate”以应用它们

my_app
的表是在
remote
数据库中创建的,而在
django_migrations
数据库的
remote
中,迁移被标记为已应用

编辑:
如何强制Django只使用一个表
Django_迁移
,但仍将迁移应用到不同的数据库中


如何在不同的数据库中应用迁移以避免出现警告?

感谢对我的问题的评论,我做了一些研究并得出了以下发现

使用多个数据库会导致在使用迁移时创建一个表
django_migrations
。正如来自的注释所解释的那样,没有选项只在一个表中记录迁移
django_migrations
。读取文件后,这一点很清楚

我将用项目中的一个项目
foo
和一个应用程序
bar
来说明一个示例。应用程序
bar
只有一个型号
Baz

我们创建项目:

django-admin startproject foo
现在,我们在主项目目录中有以下内容:

- foo
- manage.py
mkdir foo/bar
python manage.py bar foo/bar
我习惯将项目目录中的所有应用分组:

- foo
- manage.py
mkdir foo/bar
python manage.py bar foo/bar
在文件
foo/settings.py
中,我们调整设置以使用两个不同的数据库,在本例中,我们使用
sqlite3

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db1.sqlite3'),
    },
    'remote': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db2.sqlite3'),
    }
}
现在我们运行迁移:

python manage.py migrate --database=default
python manage.py makemigrations bar
这将运行所有迁移,部分
--database=default
是可选的,因为如果未指定,Django将使用默认数据库

Operations to perform: Apply all migrations: admin, auth, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying auth.0010_alter_group_name_max_length... OK Applying auth.0011_update_proxy_permissions... OK Applying sessions.0001_initial... OK 将应用程序
bar
注册到
INSTALLED_APPS
foo/settings.py
)并创建迁移:

python manage.py migrate --database=default
python manage.py makemigrations bar
在运行迁移之前,我们在
应用程序中创建
路由器.py

class BarRouter(object): def db_for_read(self, model, **hints): if model._meta.app_label == 'bar': return 'remote' return None def db_for_write(self, model, **hints): if model._meta.app_label == 'bar': return 'remote' return None def allow_relation(self, obj1, obj2, **hints): return None def allow_migrate(self, db, app_label, model_name=None, **hints): if app_label == 'bar': return db == 'remote' if db == 'remote': return False return None 现在最简单的方法是将
bar
迁移到
remote
数据库:

1 contenttypes 0001_initial 2019-11-13 16:51:04.767382 2 auth 0001_initial 2019-11-13 16:51:04.792245 3 admin 0001_initial 2019-11-13 16:51:04.827454 4 admin 0002_logentr 2019-11-13 16:51:04.846627 5 admin 0003_logentr 2019-11-13 16:51:04.864458 6 contenttypes 0002_remove_ 2019-11-13 16:51:04.892220 7 auth 0002_alter_p 2019-11-13 16:51:04.906449 8 auth 0003_alter_u 2019-11-13 16:51:04.923902 9 auth 0004_alter_u 2019-11-13 16:51:04.941707 10 auth 0005_alter_u 2019-11-13 16:51:04.958371 11 auth 0006_require 2019-11-13 16:51:04.965527 12 auth 0007_alter_v 2019-11-13 16:51:04.981532 13 auth 0008_alter_u 2019-11-13 16:51:05.004149 14 auth 0009_alter_u 2019-11-13 16:51:05.019705 15 auth 0010_alter_g 2019-11-13 16:51:05.037023 16 auth 0011_update_ 2019-11-13 16:51:05.054449 17 sessions 0001_initial 2019-11-13 16:51:05.063868
python manage.py migrate bar --database=remote
1 bar 0001_initial 2019-11-13 17:32:39.701784 当我们运行时:

python manage.py runserver
将发出以下警告:

您有1个未应用的迁移。您的项目可能无法正常工作 在您为应用程序应用迁移之前:栏。
运行“python manage.py migrate”以应用它们

不过一切似乎都很好。然而,有这样的警告并不令人满意

正确的方法是按照本文的建议为每个数据库运行所有迁移

它看起来是这样的:

python manage.py migrate my_app --database=remote
python manage.py migrate --database=default
python manage.py migrate --database=remote
在为
条创建迁移后:

python manage.py migrate bar --database=default
python manage.py migrate bar --database=remote
路由器将注意表
bar_baz
仅在
remote
数据库中创建,但Django将标记两个数据库中应用的迁移。此外,
auth
admin
会话
等的表格将仅在
默认
数据库中创建,如
routers.py
中所述。
remote
数据库中的表
django_migrations
也将包含这些迁移的记录


这是一篇很长的文章,但我希望它能对这一问题有所启发。我认为,官方并没有对这一问题进行透彻的解释。

对于其他非“我的应用”,allow\u migrate没有返回任何结果。也许你想在那里再做一次检查?据我从你的路由器了解,“我的应用程序”使用“远程”数据库,而所有其他应用程序将使用“默认”数据库?@cezar你要求的几乎是不可能的。为了共享
django_迁移
表,需要区分迁移为
default
remote
db的行。这在django内部相当深入。我甚至会冒险说,这将需要对迁移代码进行重大重写。@KamilNiski感谢您分享您的想法。我将改写这个问题。可能是相关的。