Sorum üzerine yaptığım yorumlar sayesinde biraz araştırma yaptım ve aşağıdaki bulguları buldum.
Birden çok veritabanının django_migrations
kullanılması, taşıma işlemleri kullanıldığında tablo oluşturulmasına neden olur. Kamil Niski'nin açıkladığı django_migrations
gibi, taşıma işlemlerini yalnızca bir tabloya kaydetme seçeneği yoktur . Bu, dosyayı okuduktan sonra açıktır .django/db/migrations/recorder.py
Bir proje foo
ve proje bar
içindeki bir uygulama ile bir örnek göstereceğim . Uygulamanın bar
sadece bir modeli vardır Baz
.
Projeyi yaratıyoruz:
django-admin startproject foo
Şimdi bu içerikler ana proje dizininde:
- foo
- manage.py
Proje dizinindeki tüm uygulamaları gruplandırma alışkanlığım var:
mkdir foo/bar
python manage.py bar foo/bar
Dosyada foo/settings.py
, ayarları iki farklı veritabanı kullanacak şekilde ayarlıyoruz, bu örneğin amaçları için kullanıyoruz 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'),
}
}
Şimdi taşıma işlemini gerçekleştiriyoruz:
python manage.py migrate --database=default
Bu, tüm geçişleri çalıştırır, bölüm --database=default
isteğe bağlıdır, çünkü belirtilmezse Django varsayılan veritabanını kullanır.
Gerçekleştirilecek işlemler:
Tüm taşıma işlemlerini uygulama: yönetici, kimlik doğrulama, içerik türleri, oturumlar
Taşıma taşıma işlemleri:
İçerik türleri uygulanıyor.0001_initial ... Tamam
Auth.0001_initial uygulanıyor ... Tamam
Admin.0001_initial uygulanıyor ... TAMAM
Admin.0002_logentry_remove_auto_add uygulanıyor ... TAMAM
Admin.0003_logentry_add_action_flag_choices uygulanıyor ... TAMAM
İçerik türleri uygulanıyor.0002_remove_content_type_name ... Tamam
Auth.0002_alter_permission_name_max_length uygulanıyor ... TAMAM
Auth.0003_alter_user_email_max_length uygulanıyor ... TAMAM
Auth.0004_alter_user_username_opts uygulanıyor ... TAMAM
Auth.0005_alter_user_last_login_null uygulanıyor ... Tamam
Auth.0006_require_contenttypes_0002 uygulanıyor ... Tamam
Auth.0007_alter_validators_add_error_messages uygulanıyor ... Tamam
Auth.0008_alter_user_username_max_length uygulanıyor ... TAMAM
Auth.0009_alter_user_last_name_max_length uygulanıyor ... TAMAM
Auth.0010_alter_group_name_max_length uygulanıyor ... TAMAM
Auth.0011_update_proxy_permissions uygulanıyor ... Tamam
Oturumlar uygulanıyor.0001_initial ... Tamam
Django tüm geçişleri varsayılan veritabanına uyguladı:
1 içerik türü 0001_initial 2019-11-13 16: 51: 04.767382
2 kimlik doğrulaması 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 içerik türü 0002_remove_ 2019-11-13 16: 51: 04.892220
7 kimlik doğrulaması 0002_alter_p 2019-11-13 16: 51: 04.906449
8 kimlik doğrulaması 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 kimlik doğrulaması 0011_update_ 2019-11-13 16: 51: 05.054449
17 oturum 0001_başlangıç 2019-11-13 16: 51: 05.063868
Şimdi modeli oluşturuyoruz Baz
:
models.py
:
from django.db import models
class Baz(models.Model):
name = models.CharField(max_length=255, unique=True)
Uygulamayı ( ) bar
içine kaydedin ve temalar oluşturun:INSTALLED_APPS
foo/settings.py
python manage.py makemigrations bar
Uygulamanın routers.py
içinde oluşturduğumuz taşıma işlemlerini çalıştırmadan önce bar
:
sınıf BarRouter (nesne):
def db_for_read (benlik, model, ** ipuçları):
model._meta.app_label == 'bar' ise:
'uzaktan' döndür
dönüş Yok
def db_for_write (benlik, model, ** ipuçları):
model._meta.app_label == 'bar' ise:
'uzaktan' döndür
dönüş Yok
def allow_relation (self, obj1, obj2, ** ipuçları):
dönüş Yok
def allow_migrate (self, db, app_label, model_name = None, ** ipuçları):
app_label == 'bar' ise:
return db == 'uzak'
db == 'uzak' ise:
Yanlış döndür
dönüş Yok
ve kaydedin foo/settings.py
:
DATABASE_ROUTERS = ['foo.bar.routers.BarRouter']
Şimdi saf yaklaşım bar
, remote
veritabanına geçişleri çalıştırmak olacaktır :
python manage.py migrate bar --database=remote
Gerçekleştirilecek işlemler:
Tüm taşıma işlemlerini uygula: bar
Çalışan taşıma işlemlerini gerçekleştirme:
Bar.0001_initial uygulanıyor ... Tamam
Taşımalar remote
veritabanına uygulandı :
1 çubuk 0001_initial 2019-11-13 17: 32: 39.701784
Koştuğumuzda:
python manage.py runserver
aşağıdaki uyarı verilecektir:
Uygulanmamış 1 taşıma işleminiz var. Uygulama (lar): çubuğu taşımalarını uygulayana kadar projeniz düzgün çalışmayabilir.
Bunları uygulamak için 'python manage.py migrate' komutunu çalıştırın.
Her şey olsa iyi çalışıyor gibi görünüyor. Ancak bu uyarıyı almak tatmin edici değil.
Doğru yanıt , bu yanıtta önerildiği gibi her veritabanı için tüm geçişleri çalıştırmak olacaktır .
Şöyle görünecektir:
python manage.py migrate --database=default
python manage.py migrate --database=remote
ve aşağıdakiler için taşıma işlemleri oluşturduktan sonra bar
:
python manage.py migrate bar --database=default
python manage.py migrate bar --database=remote
Yönlendirici, tablonun bar_baz
yalnızca remote
veritabanında oluşturulmasına özen gösterir , ancak Django taşıma işlemlerini her iki veritabanında da uygulanmış olarak işaretler. İçin de masalar auth
, admin
, sessions
vb sadece oluşturulacak default
belirtildiği gibi, veritabanı routers.py
. Tablo django_migrations
içinde remote
veritabanı bunları da göçler için kayıtları olacaktır.
Uzun bir okuma, ama umarım bence, resmi belgelerde tam olarak açıklanmayan bir konuya ışık tutuyor .