Как использовать несколько баз данных в Django с пустым 'default'?
Я пытаюсь сделать проект с несколькими базами данных в Django. Но у меня возникают проблемы с правильной миграцией моих моделей в соответствующую базу данных.
Я использую учебник "Написание вашего первого приложения Django" в качестве отправной точки; итак ... Я написал следующие маршрутизаторы базы данных; этот для приложения '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 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' (для нативных приложений 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
Проблема в том, что когда я проверяю вывод sqlmigrate для приложения devices, я не могу увидеть правильный 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 для 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. Но у меня возникают проблемы с правильной миграцией моих моделей в соответствующую базу данных.
Я использую учебник "Написание вашего первого приложения Django" в качестве отправной точки; итак ... Я написал следующие маршрутизаторы базы данных; этот для приложения '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 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' (для нативных приложений 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
Проблема в том, что когда я проверяю вывод sqlmigrate для приложения devices, я не могу увидеть правильный 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 для 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 сгенерирована правильно! (Я не вставляю его, чтобы не делать этот пост длиннее)
Так что я не понимаю, почему 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 сгенерирована правильно!:
Так что я не понимаю, почему 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 генерировать модель из SQL скрипта с помощью python manage.py inspectdb > models.py и это устанавливает по умолчанию managed = False