如何在空 'default' 的 Django 中使用多个数据库?
How to use multiple databases in Django with an empty 'default'?
我正在尝试在 Django 中创建一个多数据库项目。但是我在将我的模型正确迁移到适当的数据库时遇到了问题。
我使用 'Writing your first Django app' 教程作为起点;所以...我写了以下数据库路由器;这个用于 'polls' 应用程序:
class PollsRouter:
route_app_labels = {'polls'}
def db_for_read(self, model, **hint):
if model._meta.app_label == 'polls':
return 'Polls'
return None
def db_for_rite(self, model, **hint):
if model._meta.app_label == 'polls':
return 'Polls'
return None
def allow_relation(self, obj1, obj2, **hint):
if (
obj1._meta.app_label == 'polls' or
obj2._meta.app_label == 'polls'
):
return True
return None
def allow_migrates(self, db, app_label, model_name=None, **hints):
if app_label == 'polls':
return db == 'Polls'
return None
还有 'devices' 应用程序的路由器 class:
class DevicesRouter:
route_app_labels = {'devices'}
def db_for_read(self, model, **hint):
if model._meta.app_label == 'devices':
return 'CTS_ER_BD'
return None
def db_for_rite(self, model, **hint):
if model._meta.app_label == 'devices':
return 'CTS_ER_BD'
return None
def allow_relation(self, obj1, obj2, **hint):
if (
obj1._meta.app_label == 'devices' or
obj2._meta.app_label == 'devices'
):
return True
return None
def allow_migrates(self, db, app_label, model_name=None, **hints):
if app_label == 'devices':
return db == 'CTS_ER_BD'
return None
最后,'auth_user' 数据库的路由器 class(对于本机 Django 应用程序)
class Auth_userRouter:
route_app_labels = {'auth', 'contenttypes', 'admin', 'sessions'}
def db_for_read(self, model, **hints):
if model._meta.app_label in self.route_app_labels:
return 'Auth_user_db'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label in self.route_app_labels:
return 'Auth_user_db'
return None
def allow_relation(self, obj1, obj2, **hints):
if (
obj1._meta.app_label in self.route_app_labels or
obj2._meta.app_label in self.route_app_labels
):
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label in self.route_app_labels:
return db == 'Auth_user_db'
return None
当然...我已经将我的应用程序和路由器包含在 settings.py 中,如下所示:
DATABASES = {
'default': {},
'Auth_user_db': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'auth_db',
'HOST': '172.18.0.2',
'USER': 'root',
'PASSWORD': 'pass'
},
'CTS_ER_BD': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'CTS_ER_BD',
'HOST': '172.18.0.2',
'USER': 'root',
'PASSWORD': 'pass'
},
'Polls': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'polls',
'HOST': '172.18.0.2',
'USER': 'root',
'PASSWORD': 'pass'
}
}
DATABASE_ROUTERS = [
'routers.Polls_router.PollsRouter',
'routers.Devices_router.DevicesRouter',
'routers.Auth_user_router.Auth_userRouter'
]
当我尝试执行迁移时出现问题,这是我在创建迁移文件之前的项目树:
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ tree .
.
├── devices
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── manage.py
├── multiple-DB
│ ├── asgi.py
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── polls
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
└── routers
├── Auth_user_router.py
├── Devices_router.py
└── Polls_router.py
4 directories, 23 files
显然迁移已正确创建为:
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py makemigrations polls
Migrations for 'polls':
polls/migrations/0001_initial.py
- Create model Question
- Create model Choice
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py makemigrations devices
Migrations for 'devices':
devices/migrations/0001_initial.py
- Create model AuthUsers
- Create model Devices
- Create model DeviceTypes
- Create model FirmwareVers
- Create model HardwareVers
- Create model Historicals
- Create model Metadata
- Create model Projects
- Create model SoftwareVers
- Create model Tests
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ tree .
.
├── devices
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ └── __init__.cpython-39.pyc
│ ├── models.py
│ ├── __pycache__
│ │ ├── admin.cpython-39.pyc
│ │ ├── apps.cpython-39.pyc
│ │ ├── __init__.cpython-39.pyc
│ │ ├── models.cpython-39.pyc
│ │ ├── urls.cpython-39.pyc
│ │ └── views.cpython-39.pyc
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── manage.py
├── multiple-DB
│ ├── asgi.py
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-39.pyc
│ │ ├── settings.cpython-39.pyc
│ │ └── urls.cpython-39.pyc
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── polls
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ ├── 0001_initial.cpython-39.pyc
│ │ └── __init__.cpython-39.pyc
│ ├── models.py
│ ├── __pycache__
│ │ ├── admin.cpython-39.pyc
│ │ ├── apps.cpython-39.pyc
│ │ ├── __init__.cpython-39.pyc
│ │ ├── models.cpython-39.pyc
│ │ ├── urls.cpython-39.pyc
│ │ └── views.cpython-39.pyc
│ ├── tests.py
│ ├── urls.py
│ └── views.py
└── routers
├── Auth_user_router.py
├── Devices_router.py
├── Polls_router.py
└── __pycache__
├── Auth_user_router.cpython-39.pyc
├── Devices_router.cpython-39.pyc
└── Polls_router.cpython-39.pyc
12 directories, 48 files
问题是,当我检查 devices
应用程序的 sqlmigrate
输出时,我看不到正确的 SQL 脚本:
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py sqlmigrate devices 0001 --database=CTS_ER_BD
--
-- Create model AuthUsers
--
--
-- Create model Devices
--
--
-- Create model DeviceTypes
--
--
-- Create model FirmwareVers
--
--
-- Create model HardwareVers
--
--
-- Create model Historicals
--
--
-- Create model Metadata
--
--
-- Create model Projects
--
--
-- Create model SoftwareVers
--
--
-- Create model Tests
--
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$
这导致当我 运行 python3 manage.py migrate devices --database=CTS_ER_BD
for devices
:
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py migrate devices --database=CTS_ER_BD
Operations to perform:
Apply all migrations: devices
Running migrations:
Applying devices.0001_initial... OK
伙计们,我正在尝试在 Django 中创建一个多数据库项目。但是我在将我的模型正确迁移到适当的数据库时遇到了问题。
我使用 'Writing your first Django app' 教程作为起点;所以...我写了以下数据库路由器;这个用于 'polls' 应用程序:
class PollsRouter:
route_app_labels = {'polls'}
def db_for_read(self, model, **hint):
if model._meta.app_label == 'polls':
return 'Polls'
return None
def db_for_rite(self, model, **hint):
if model._meta.app_label == 'polls':
return 'Polls'
return None
def allow_relation(self, obj1, obj2, **hint):
if (
obj1._meta.app_label == 'polls' or
obj2._meta.app_label == 'polls'
):
return True
return None
def allow_migrates(self, db, app_label, model_name=None, **hints):
if app_label == 'polls':
return db == 'Polls'
return None
还有 'devices' 应用程序的路由器 class:
class DevicesRouter:
route_app_labels = {'devices'}
def db_for_read(self, model, **hint):
if model._meta.app_label == 'devices':
return 'CTS_ER_BD'
return None
def db_for_rite(self, model, **hint):
if model._meta.app_label == 'devices':
return 'CTS_ER_BD'
return None
def allow_relation(self, obj1, obj2, **hint):
if (
obj1._meta.app_label == 'devices' or
obj2._meta.app_label == 'devices'
):
return True
return None
def allow_migrates(self, db, app_label, model_name=None, **hints):
if app_label == 'devices':
return db == 'CTS_ER_BD'
return None
最后,'auth_user' 数据库的路由器 class(对于本机 Django 应用程序)
class Auth_userRouter:
route_app_labels = {'auth', 'contenttypes', 'admin', 'sessions'}
def db_for_read(self, model, **hints):
if model._meta.app_label in self.route_app_labels:
return 'Auth_user_db'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label in self.route_app_labels:
return 'Auth_user_db'
return None
def allow_relation(self, obj1, obj2, **hints):
if (
obj1._meta.app_label in self.route_app_labels or
obj2._meta.app_label in self.route_app_labels
):
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label in self.route_app_labels:
return db == 'Auth_user_db'
return None
当然...我已经将我的应用程序和路由器包含在 settings.py 中,如下所示:
DATABASES = {
'default': {},
'Auth_user_db': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'auth_db',
'HOST': '172.18.0.2',
'USER': 'root',
'PASSWORD': 'pass'
},
'CTS_ER_BD': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'CTS_ER_BD',
'HOST': '172.18.0.2',
'USER': 'root',
'PASSWORD': 'pass'
},
'Polls': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'polls',
'HOST': '172.18.0.2',
'USER': 'root',
'PASSWORD': 'pass'
}
}
DATABASE_ROUTERS = [
'routers.Polls_router.PollsRouter',
'routers.Devices_router.DevicesRouter',
'routers.Auth_user_router.Auth_userRouter'
]
当我尝试执行迁移时出现问题,这是我在创建迁移文件之前的项目树:
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ tree .
.
├── devices
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── manage.py
├── multiple-DB
│ ├── asgi.py
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── polls
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
└── routers
├── Auth_user_router.py
├── Devices_router.py
└── Polls_router.py
4 directories, 23 files
显然迁移已正确创建为:
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py makemigrations polls
Migrations for 'polls':
polls/migrations/0001_initial.py
- Create model Question
- Create model Choice
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py makemigrations devices
Migrations for 'devices':
devices/migrations/0001_initial.py
- Create model AuthUsers
- Create model Devices
- Create model DeviceTypes
- Create model FirmwareVers
- Create model HardwareVers
- Create model Historicals
- Create model Metadata
- Create model Projects
- Create model SoftwareVers
- Create model Tests
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ tree .
.
├── devices
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ └── __init__.cpython-39.pyc
│ ├── models.py
│ ├── __pycache__
│ │ ├── admin.cpython-39.pyc
│ │ ├── apps.cpython-39.pyc
│ │ ├── __init__.cpython-39.pyc
│ │ ├── models.cpython-39.pyc
│ │ ├── urls.cpython-39.pyc
│ │ └── views.cpython-39.pyc
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── manage.py
├── multiple-DB
│ ├── asgi.py
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-39.pyc
│ │ ├── settings.cpython-39.pyc
│ │ └── urls.cpython-39.pyc
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── polls
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ ├── 0001_initial.cpython-39.pyc
│ │ └── __init__.cpython-39.pyc
│ ├── models.py
│ ├── __pycache__
│ │ ├── admin.cpython-39.pyc
│ │ ├── apps.cpython-39.pyc
│ │ ├── __init__.cpython-39.pyc
│ │ ├── models.cpython-39.pyc
│ │ ├── urls.cpython-39.pyc
│ │ └── views.cpython-39.pyc
│ ├── tests.py
│ ├── urls.py
│ └── views.py
└── routers
├── Auth_user_router.py
├── Devices_router.py
├── Polls_router.py
└── __pycache__
├── Auth_user_router.cpython-39.pyc
├── Devices_router.cpython-39.pyc
└── Polls_router.cpython-39.pyc
12 directories, 48 files
问题是,当我检查 devices
应用程序的 sqlmigrate
输出时,我看不到正确的 SQL 脚本:
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py sqlmigrate devices 0001 --database=CTS_ER_BD
--
-- Create model AuthUsers
--
--
-- Create model Devices
--
--
-- Create model DeviceTypes
--
--
-- Create model FirmwareVers
--
--
-- Create model HardwareVers
--
--
-- Create model Historicals
--
--
-- Create model Metadata
--
--
-- Create model Projects
--
--
-- Create model SoftwareVers
--
--
-- Create model Tests
--
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$
这导致当我 运行 python3 manage.py migrate devices --database=CTS_ER_BD
for devices
:
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py migrate devices --database=CTS_ER_BD
Operations to perform:
Apply all migrations: devices
Running migrations:
Applying devices.0001_initial... OK
未创建相应数据库中的表:
MySQL [CTS_ER_BD]> SHOW TABLES;
+---------------------+
| Tables_in_CTS_ER_BD |
+---------------------+
| django_migrations |
+---------------------+
但显然 devices
应用程序的迁移已正确生成! (我没有粘贴它,以免 post 变长)
所以我不明白为什么 sqlmigrate
没有显示正确的 sql 脚本。或者没有正确执行迁移。
我不确定这是否可能是因为两个迁移文件实际上以相同的方式调用 (0001_initial.py
),我是否应该为每个应用程序选择一个不同的文件?无论如何......两者都在不同的文件夹中,所以我没有看到任何问题。
民意调查和 Django 本机应用程序的迁移正常工作(显然),事实上,对于 'polls' 应用程序,您可以看到 sqlmigrate
的正确输出
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py sqlmigrate polls 0001 --database=Polls
--
-- Create model Question
--
CREATE TABLE `polls_question` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `question_text` varchar(200) NOT NULL, `pub_date` datetime(6) NOT NULL);
--
-- Create model Choice
--
CREATE TABLE `polls_choice` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `choice_text` varchar(200) NOT NULL, `votes` integer NOT NULL, `question_id` bigint NOT NULL);
ALTER TABLE `polls_choice` ADD CONSTRAINT `polls_choice_question_id_c5b4b260_fk_polls_question_id` FOREIGN KEY (`question_id`) REFERENCES `polls_question` (`id`);
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$
所以我不确定我做错了什么。如果你想看这个项目......我在 GitLab https://gitlab.com/ralbarran1/multiple-db-in-django
中跟踪它
非常感谢,如果问题太长或重复,我很抱歉,我可以看到几个类似的问题,但我认为太旧了。
没有创建相应的数据库:
MySQL [CTS_ER_BD]> SHOW TABLES;
+---------------------+
| Tables_in_CTS_ER_BD |
+---------------------+
| django_migrations |
+---------------------+
但显然 devices
应用程序的迁移已正确生成!:
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ cat devices/migrations/0001_initial.py
# Generated by Django 4.0.4 on 2022-04-29 09:39
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='AuthUsers',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('user_name', models.CharField(max_length=50)),
],
options={
'db_table': 'auth_users',
'managed': False,
},
),
migrations.CreateModel(
name='Devices',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('serial_number', models.IntegerField()),
('manufacture_date', models.DateTimeField(blank=True, null=True)),
('devices_tag', models.ImageField(blank=True, null=True, upload_to='')),
],
options={
'db_table': 'devices',
'managed': False,
},
),
migrations.CreateModel(
name='DeviceTypes',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('device_name', models.CharField(max_length=50)),
('client_ref', models.CharField(max_length=100)),
('colway_ref', models.CharField(max_length=100)),
('power_dis', models.IntegerField(blank=True, null=True)),
],
options={
'db_table': 'device_types',
'managed': False,
},
),
migrations.CreateModel(
name='FirmwareVers',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('firmware_name', models.CharField(blank=True, max_length=50, null=True)),
('manuf_type', models.CharField(blank=True, max_length=50, null=True)),
],
options={
'db_table': 'firmware_vers',
'managed': False,
},
),
migrations.CreateModel(
name='HardwareVers',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('hw_type', models.CharField(blank=True, db_column='HW_type', max_length=1, null=True)),
],
options={
'db_table': 'hardware_vers',
'managed': False,
},
),
migrations.CreateModel(
name='Historicals',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('test_date', models.DateTimeField(blank=True, null=True)),
('reuslt', models.BooleanField(blank=True, null=True)),
],
options={
'db_table': 'historicals',
'managed': False,
},
),
migrations.CreateModel(
name='Metadata',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
],
options={
'db_table': 'metadata',
'managed': False,
},
),
migrations.CreateModel(
name='Projects',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('project_name', models.CharField(blank=True, max_length=50, null=True)),
],
options={
'db_table': 'projects',
'managed': False,
},
),
migrations.CreateModel(
name='SoftwareVers',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('colway_ref', models.CharField(blank=True, max_length=100, null=True)),
('joifi_ref', models.CharField(blank=True, max_length=100, null=True)),
],
options={
'db_table': 'software_vers',
'managed': False,
},
),
migrations.CreateModel(
name='Tests',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('test_name', models.CharField(blank=True, max_length=50, null=True)),
('prefix', models.CharField(blank=True, max_length=1, null=True)),
],
options={
'db_table': 'tests',
'managed': False,
},
),
]
所以我不明白为什么 sqlmigrate
没有显示正确的 sql 脚本。或者没有正确执行迁移。
我不确定这是否可能是因为两个迁移文件实际上以相同的方式调用 (0001_initial.py
),我是否应该为每个应用程序选择一个不同的文件?无论如何......两者都在不同的文件夹中,所以我没有看到任何问题。
民意调查和 Django 本机应用程序的迁移正常工作(显然),事实上,对于 'polls' 应用程序,您可以看到 sqlmigrate
的正确输出
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py sqlmigrate polls 0001 --database=Polls
--
-- Create model Question
--
CREATE TABLE `polls_question` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `question_text` varchar(200) NOT NULL, `pub_date` datetime(6) NOT NULL);
--
-- Create model Choice
--
CREATE TABLE `polls_choice` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `choice_text` varchar(200) NOT NULL, `votes` integer NOT NULL, `question_id` bigint NOT NULL);
ALTER TABLE `polls_choice` ADD CONSTRAINT `polls_choice_question_id_c5b4b260_fk_polls_question_id` FOREIGN KEY (`question_id`) REFERENCES `polls_question` (`id`);
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$
所以我不确定我做错了什么。如果你想看这个项目......我在 GitLab https://gitlab.com/ralbarran1/multiple-db-in-django
中跟踪它
非常感谢,如果问题太长或重复,我很抱歉,我可以看到几个类似的问题,但我认为太旧了。
问题实际上出在模型中:
class DeviceTypes(models.Model):
device_name = models.CharField(max_length=50)
client_ref = models.CharField(max_length=100)
colway_ref = models.CharField(max_length=100)
power_dis = models.IntegerField(blank=True, null=True)
def __str__(self):
return f'{self.colway_ref}', {self.device_name}
class Meta:
managed = Fase
db_table = 'device_types'
此 META OPTIONS managed = False
阻止 Django 管理此模型。
这是因为我让 Django 使用 python manage.py inspectdb > models.py
从 SQL 脚本生成模型,默认设置为 managed = False
我正在尝试在 Django 中创建一个多数据库项目。但是我在将我的模型正确迁移到适当的数据库时遇到了问题。
我使用 'Writing your first Django app' 教程作为起点;所以...我写了以下数据库路由器;这个用于 'polls' 应用程序:
class PollsRouter:
route_app_labels = {'polls'}
def db_for_read(self, model, **hint):
if model._meta.app_label == 'polls':
return 'Polls'
return None
def db_for_rite(self, model, **hint):
if model._meta.app_label == 'polls':
return 'Polls'
return None
def allow_relation(self, obj1, obj2, **hint):
if (
obj1._meta.app_label == 'polls' or
obj2._meta.app_label == 'polls'
):
return True
return None
def allow_migrates(self, db, app_label, model_name=None, **hints):
if app_label == 'polls':
return db == 'Polls'
return None
还有 'devices' 应用程序的路由器 class:
class DevicesRouter:
route_app_labels = {'devices'}
def db_for_read(self, model, **hint):
if model._meta.app_label == 'devices':
return 'CTS_ER_BD'
return None
def db_for_rite(self, model, **hint):
if model._meta.app_label == 'devices':
return 'CTS_ER_BD'
return None
def allow_relation(self, obj1, obj2, **hint):
if (
obj1._meta.app_label == 'devices' or
obj2._meta.app_label == 'devices'
):
return True
return None
def allow_migrates(self, db, app_label, model_name=None, **hints):
if app_label == 'devices':
return db == 'CTS_ER_BD'
return None
最后,'auth_user' 数据库的路由器 class(对于本机 Django 应用程序)
class Auth_userRouter:
route_app_labels = {'auth', 'contenttypes', 'admin', 'sessions'}
def db_for_read(self, model, **hints):
if model._meta.app_label in self.route_app_labels:
return 'Auth_user_db'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label in self.route_app_labels:
return 'Auth_user_db'
return None
def allow_relation(self, obj1, obj2, **hints):
if (
obj1._meta.app_label in self.route_app_labels or
obj2._meta.app_label in self.route_app_labels
):
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label in self.route_app_labels:
return db == 'Auth_user_db'
return None
当然...我已经将我的应用程序和路由器包含在 settings.py 中,如下所示:
DATABASES = {
'default': {},
'Auth_user_db': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'auth_db',
'HOST': '172.18.0.2',
'USER': 'root',
'PASSWORD': 'pass'
},
'CTS_ER_BD': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'CTS_ER_BD',
'HOST': '172.18.0.2',
'USER': 'root',
'PASSWORD': 'pass'
},
'Polls': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'polls',
'HOST': '172.18.0.2',
'USER': 'root',
'PASSWORD': 'pass'
}
}
DATABASE_ROUTERS = [
'routers.Polls_router.PollsRouter',
'routers.Devices_router.DevicesRouter',
'routers.Auth_user_router.Auth_userRouter'
]
当我尝试执行迁移时出现问题,这是我在创建迁移文件之前的项目树:
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ tree .
.
├── devices
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── manage.py
├── multiple-DB
│ ├── asgi.py
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── polls
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
└── routers
├── Auth_user_router.py
├── Devices_router.py
└── Polls_router.py
4 directories, 23 files
显然迁移已正确创建为:
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py makemigrations polls
Migrations for 'polls':
polls/migrations/0001_initial.py
- Create model Question
- Create model Choice
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py makemigrations devices
Migrations for 'devices':
devices/migrations/0001_initial.py
- Create model AuthUsers
- Create model Devices
- Create model DeviceTypes
- Create model FirmwareVers
- Create model HardwareVers
- Create model Historicals
- Create model Metadata
- Create model Projects
- Create model SoftwareVers
- Create model Tests
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ tree .
.
├── devices
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ └── __init__.cpython-39.pyc
│ ├── models.py
│ ├── __pycache__
│ │ ├── admin.cpython-39.pyc
│ │ ├── apps.cpython-39.pyc
│ │ ├── __init__.cpython-39.pyc
│ │ ├── models.cpython-39.pyc
│ │ ├── urls.cpython-39.pyc
│ │ └── views.cpython-39.pyc
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── manage.py
├── multiple-DB
│ ├── asgi.py
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-39.pyc
│ │ ├── settings.cpython-39.pyc
│ │ └── urls.cpython-39.pyc
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── polls
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ ├── 0001_initial.cpython-39.pyc
│ │ └── __init__.cpython-39.pyc
│ ├── models.py
│ ├── __pycache__
│ │ ├── admin.cpython-39.pyc
│ │ ├── apps.cpython-39.pyc
│ │ ├── __init__.cpython-39.pyc
│ │ ├── models.cpython-39.pyc
│ │ ├── urls.cpython-39.pyc
│ │ └── views.cpython-39.pyc
│ ├── tests.py
│ ├── urls.py
│ └── views.py
└── routers
├── Auth_user_router.py
├── Devices_router.py
├── Polls_router.py
└── __pycache__
├── Auth_user_router.cpython-39.pyc
├── Devices_router.cpython-39.pyc
└── Polls_router.cpython-39.pyc
12 directories, 48 files
问题是,当我检查 devices
应用程序的 sqlmigrate
输出时,我看不到正确的 SQL 脚本:
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py sqlmigrate devices 0001 --database=CTS_ER_BD
--
-- Create model AuthUsers
--
--
-- Create model Devices
--
--
-- Create model DeviceTypes
--
--
-- Create model FirmwareVers
--
--
-- Create model HardwareVers
--
--
-- Create model Historicals
--
--
-- Create model Metadata
--
--
-- Create model Projects
--
--
-- Create model SoftwareVers
--
--
-- Create model Tests
--
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$
这导致当我 运行 python3 manage.py migrate devices --database=CTS_ER_BD
for devices
:
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py migrate devices --database=CTS_ER_BD
Operations to perform:
Apply all migrations: devices
Running migrations:
Applying devices.0001_initial... OK
伙计们,我正在尝试在 Django 中创建一个多数据库项目。但是我在将我的模型正确迁移到适当的数据库时遇到了问题。
我使用 'Writing your first Django app' 教程作为起点;所以...我写了以下数据库路由器;这个用于 'polls' 应用程序:
class PollsRouter:
route_app_labels = {'polls'}
def db_for_read(self, model, **hint):
if model._meta.app_label == 'polls':
return 'Polls'
return None
def db_for_rite(self, model, **hint):
if model._meta.app_label == 'polls':
return 'Polls'
return None
def allow_relation(self, obj1, obj2, **hint):
if (
obj1._meta.app_label == 'polls' or
obj2._meta.app_label == 'polls'
):
return True
return None
def allow_migrates(self, db, app_label, model_name=None, **hints):
if app_label == 'polls':
return db == 'Polls'
return None
还有 'devices' 应用程序的路由器 class:
class DevicesRouter:
route_app_labels = {'devices'}
def db_for_read(self, model, **hint):
if model._meta.app_label == 'devices':
return 'CTS_ER_BD'
return None
def db_for_rite(self, model, **hint):
if model._meta.app_label == 'devices':
return 'CTS_ER_BD'
return None
def allow_relation(self, obj1, obj2, **hint):
if (
obj1._meta.app_label == 'devices' or
obj2._meta.app_label == 'devices'
):
return True
return None
def allow_migrates(self, db, app_label, model_name=None, **hints):
if app_label == 'devices':
return db == 'CTS_ER_BD'
return None
最后,'auth_user' 数据库的路由器 class(对于本机 Django 应用程序)
class Auth_userRouter:
route_app_labels = {'auth', 'contenttypes', 'admin', 'sessions'}
def db_for_read(self, model, **hints):
if model._meta.app_label in self.route_app_labels:
return 'Auth_user_db'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label in self.route_app_labels:
return 'Auth_user_db'
return None
def allow_relation(self, obj1, obj2, **hints):
if (
obj1._meta.app_label in self.route_app_labels or
obj2._meta.app_label in self.route_app_labels
):
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label in self.route_app_labels:
return db == 'Auth_user_db'
return None
当然...我已经将我的应用程序和路由器包含在 settings.py 中,如下所示:
DATABASES = {
'default': {},
'Auth_user_db': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'auth_db',
'HOST': '172.18.0.2',
'USER': 'root',
'PASSWORD': 'pass'
},
'CTS_ER_BD': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'CTS_ER_BD',
'HOST': '172.18.0.2',
'USER': 'root',
'PASSWORD': 'pass'
},
'Polls': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'polls',
'HOST': '172.18.0.2',
'USER': 'root',
'PASSWORD': 'pass'
}
}
DATABASE_ROUTERS = [
'routers.Polls_router.PollsRouter',
'routers.Devices_router.DevicesRouter',
'routers.Auth_user_router.Auth_userRouter'
]
当我尝试执行迁移时出现问题,这是我在创建迁移文件之前的项目树:
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ tree .
.
├── devices
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── manage.py
├── multiple-DB
│ ├── asgi.py
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── polls
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
└── routers
├── Auth_user_router.py
├── Devices_router.py
└── Polls_router.py
4 directories, 23 files
显然迁移已正确创建为:
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py makemigrations polls
Migrations for 'polls':
polls/migrations/0001_initial.py
- Create model Question
- Create model Choice
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py makemigrations devices
Migrations for 'devices':
devices/migrations/0001_initial.py
- Create model AuthUsers
- Create model Devices
- Create model DeviceTypes
- Create model FirmwareVers
- Create model HardwareVers
- Create model Historicals
- Create model Metadata
- Create model Projects
- Create model SoftwareVers
- Create model Tests
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ tree .
.
├── devices
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ └── __init__.cpython-39.pyc
│ ├── models.py
│ ├── __pycache__
│ │ ├── admin.cpython-39.pyc
│ │ ├── apps.cpython-39.pyc
│ │ ├── __init__.cpython-39.pyc
│ │ ├── models.cpython-39.pyc
│ │ ├── urls.cpython-39.pyc
│ │ └── views.cpython-39.pyc
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── manage.py
├── multiple-DB
│ ├── asgi.py
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-39.pyc
│ │ ├── settings.cpython-39.pyc
│ │ └── urls.cpython-39.pyc
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── polls
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ ├── 0001_initial.cpython-39.pyc
│ │ └── __init__.cpython-39.pyc
│ ├── models.py
│ ├── __pycache__
│ │ ├── admin.cpython-39.pyc
│ │ ├── apps.cpython-39.pyc
│ │ ├── __init__.cpython-39.pyc
│ │ ├── models.cpython-39.pyc
│ │ ├── urls.cpython-39.pyc
│ │ └── views.cpython-39.pyc
│ ├── tests.py
│ ├── urls.py
│ └── views.py
└── routers
├── Auth_user_router.py
├── Devices_router.py
├── Polls_router.py
└── __pycache__
├── Auth_user_router.cpython-39.pyc
├── Devices_router.cpython-39.pyc
└── Polls_router.cpython-39.pyc
12 directories, 48 files
问题是,当我检查 devices
应用程序的 sqlmigrate
输出时,我看不到正确的 SQL 脚本:
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py sqlmigrate devices 0001 --database=CTS_ER_BD
--
-- Create model AuthUsers
--
--
-- Create model Devices
--
--
-- Create model DeviceTypes
--
--
-- Create model FirmwareVers
--
--
-- Create model HardwareVers
--
--
-- Create model Historicals
--
--
-- Create model Metadata
--
--
-- Create model Projects
--
--
-- Create model SoftwareVers
--
--
-- Create model Tests
--
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$
这导致当我 运行 python3 manage.py migrate devices --database=CTS_ER_BD
for devices
:
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py migrate devices --database=CTS_ER_BD
Operations to perform:
Apply all migrations: devices
Running migrations:
Applying devices.0001_initial... OK
未创建相应数据库中的表:
MySQL [CTS_ER_BD]> SHOW TABLES;
+---------------------+
| Tables_in_CTS_ER_BD |
+---------------------+
| django_migrations |
+---------------------+
但显然 devices
应用程序的迁移已正确生成! (我没有粘贴它,以免 post 变长)
所以我不明白为什么 sqlmigrate
没有显示正确的 sql 脚本。或者没有正确执行迁移。
我不确定这是否可能是因为两个迁移文件实际上以相同的方式调用 (0001_initial.py
),我是否应该为每个应用程序选择一个不同的文件?无论如何......两者都在不同的文件夹中,所以我没有看到任何问题。
民意调查和 Django 本机应用程序的迁移正常工作(显然),事实上,对于 'polls' 应用程序,您可以看到 sqlmigrate
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py sqlmigrate polls 0001 --database=Polls
--
-- Create model Question
--
CREATE TABLE `polls_question` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `question_text` varchar(200) NOT NULL, `pub_date` datetime(6) NOT NULL);
--
-- Create model Choice
--
CREATE TABLE `polls_choice` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `choice_text` varchar(200) NOT NULL, `votes` integer NOT NULL, `question_id` bigint NOT NULL);
ALTER TABLE `polls_choice` ADD CONSTRAINT `polls_choice_question_id_c5b4b260_fk_polls_question_id` FOREIGN KEY (`question_id`) REFERENCES `polls_question` (`id`);
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$
所以我不确定我做错了什么。如果你想看这个项目......我在 GitLab https://gitlab.com/ralbarran1/multiple-db-in-django
中跟踪它非常感谢,如果问题太长或重复,我很抱歉,我可以看到几个类似的问题,但我认为太旧了。
没有创建相应的数据库:
MySQL [CTS_ER_BD]> SHOW TABLES;
+---------------------+
| Tables_in_CTS_ER_BD |
+---------------------+
| django_migrations |
+---------------------+
但显然 devices
应用程序的迁移已正确生成!:
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ cat devices/migrations/0001_initial.py
# Generated by Django 4.0.4 on 2022-04-29 09:39
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='AuthUsers',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('user_name', models.CharField(max_length=50)),
],
options={
'db_table': 'auth_users',
'managed': False,
},
),
migrations.CreateModel(
name='Devices',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('serial_number', models.IntegerField()),
('manufacture_date', models.DateTimeField(blank=True, null=True)),
('devices_tag', models.ImageField(blank=True, null=True, upload_to='')),
],
options={
'db_table': 'devices',
'managed': False,
},
),
migrations.CreateModel(
name='DeviceTypes',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('device_name', models.CharField(max_length=50)),
('client_ref', models.CharField(max_length=100)),
('colway_ref', models.CharField(max_length=100)),
('power_dis', models.IntegerField(blank=True, null=True)),
],
options={
'db_table': 'device_types',
'managed': False,
},
),
migrations.CreateModel(
name='FirmwareVers',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('firmware_name', models.CharField(blank=True, max_length=50, null=True)),
('manuf_type', models.CharField(blank=True, max_length=50, null=True)),
],
options={
'db_table': 'firmware_vers',
'managed': False,
},
),
migrations.CreateModel(
name='HardwareVers',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('hw_type', models.CharField(blank=True, db_column='HW_type', max_length=1, null=True)),
],
options={
'db_table': 'hardware_vers',
'managed': False,
},
),
migrations.CreateModel(
name='Historicals',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('test_date', models.DateTimeField(blank=True, null=True)),
('reuslt', models.BooleanField(blank=True, null=True)),
],
options={
'db_table': 'historicals',
'managed': False,
},
),
migrations.CreateModel(
name='Metadata',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
],
options={
'db_table': 'metadata',
'managed': False,
},
),
migrations.CreateModel(
name='Projects',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('project_name', models.CharField(blank=True, max_length=50, null=True)),
],
options={
'db_table': 'projects',
'managed': False,
},
),
migrations.CreateModel(
name='SoftwareVers',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('colway_ref', models.CharField(blank=True, max_length=100, null=True)),
('joifi_ref', models.CharField(blank=True, max_length=100, null=True)),
],
options={
'db_table': 'software_vers',
'managed': False,
},
),
migrations.CreateModel(
name='Tests',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('test_name', models.CharField(blank=True, max_length=50, null=True)),
('prefix', models.CharField(blank=True, max_length=1, null=True)),
],
options={
'db_table': 'tests',
'managed': False,
},
),
]
所以我不明白为什么 sqlmigrate
没有显示正确的 sql 脚本。或者没有正确执行迁移。
我不确定这是否可能是因为两个迁移文件实际上以相同的方式调用 (0001_initial.py
),我是否应该为每个应用程序选择一个不同的文件?无论如何......两者都在不同的文件夹中,所以我没有看到任何问题。
民意调查和 Django 本机应用程序的迁移正常工作(显然),事实上,对于 'polls' 应用程序,您可以看到 sqlmigrate
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$ python3 manage.py sqlmigrate polls 0001 --database=Polls
--
-- Create model Question
--
CREATE TABLE `polls_question` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `question_text` varchar(200) NOT NULL, `pub_date` datetime(6) NOT NULL);
--
-- Create model Choice
--
CREATE TABLE `polls_choice` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `choice_text` varchar(200) NOT NULL, `votes` integer NOT NULL, `question_id` bigint NOT NULL);
ALTER TABLE `polls_choice` ADD CONSTRAINT `polls_choice_question_id_c5b4b260_fk_polls_question_id` FOREIGN KEY (`question_id`) REFERENCES `polls_question` (`id`);
(venv) raul@raul:~/multiple-db-in-django/multiple-DB$
所以我不确定我做错了什么。如果你想看这个项目......我在 GitLab https://gitlab.com/ralbarran1/multiple-db-in-django
中跟踪它非常感谢,如果问题太长或重复,我很抱歉,我可以看到几个类似的问题,但我认为太旧了。
问题实际上出在模型中:
class DeviceTypes(models.Model):
device_name = models.CharField(max_length=50)
client_ref = models.CharField(max_length=100)
colway_ref = models.CharField(max_length=100)
power_dis = models.IntegerField(blank=True, null=True)
def __str__(self):
return f'{self.colway_ref}', {self.device_name}
class Meta:
managed = Fase
db_table = 'device_types'
此 META OPTIONS managed = False
阻止 Django 管理此模型。
这是因为我让 Django 使用 python manage.py inspectdb > models.py
从 SQL 脚本生成模型,默认设置为 managed = False