データ移行の作成に苦労しています。アプリには2つのデータベースを使用しています。 settings.pyでデータベースを構成し、Django docs のようなルーターも作成しました。
# settings.py
DB_Host = 'localhost'
DATABASES = {
'default': {
'ENGINE': 'Django.db.backends.mysql',
'NAME': 'helios',
'Host': DB_Host,
'OPTIONS': {
'read_default_file': join(dirname(__file__), 'default.cnf'),
},
},
'other': {
'ENGINE': 'Django.db.backends.mysql',
'NAME': 'gala_pol',
'Host': DB_Host,
'OPTIONS': {
'read_default_file': join(dirname(__file__), 'other.cnf'),
},
},
DATABASE_APPS_MAPPING = {
'contenttypes': 'default',
'auth': 'default',
'admin': 'default',
'sessions': 'default',
'messages': 'default',
'staticfiles': 'default',
'woodsmen': 'default',
'helios': 'default',
'hush': 'default',
'hunt': 'other',
'meat': 'other',
'beast': 'other',
}
# routers.py
class DatabaseAppsRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label in settings.DATABASE_APPS_MAPPING:
return settings.DATABASE_APPS_MAPPING[model._meta.app_label]
return None
def db_for_write(self, model, **hints):
if model._meta.app_label in settings.
return settings.DATABASE_APPS_MAPPING[model._meta.app_label]
return None
def allow_relation(self, obj1, obj2, **hints):
db1 = settings.DATABASE_APPS_MAPPING.get(obj1._meta.app_label)
db2 = settings.DATABASE_APPS_MAPPING.get(obj2._meta.app_label)
if db1 and db2:
return db1 == db2
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if db in settings.DATABASE_APPS_MAPPING.values():
return settings.DATABASE_APPS_MAPPING.get(app_label) == db
Elif app_label in settings.DATABASE_APPS_MAPPING:
return False
これらのアプリの1つのモデルと移行を次に示します。
# hunt.models.py
class Dish(models.Model):
"""
Investigation case
"""
display_name = models.CharField(max_length=64, unique=True)
department = models.ForeignKey(Kitchen, null=True)
case_type = models.PositiveSmallIntegerField(choices=CASE_TYPE_CHOICES, default=DEF_CASE_TYPE)
created_at = models.DateTimeField(blank=True, null=True)
comment = models.CharField(max_length=256, blank=True, null=True)
class Meta:
verbose_name = 'case'
app_label = 'hunt'
def __unicode__(self):
return (u'%s (%s)' % (self.display_name, self.created_at)).strip()
# hunt.migrations.0001_initial.py
class Migration(migrations.Migration):
app_label = 'hunt'
dependencies = [
]
operations = [
migrations.CreateModel(
name='Dish',
fields=[
('id', models.AutoField(verbose_name='ID', auto_created=True, primary_key=True, serialize=False)),
('display_name', models.CharField(max_length=64, unique=True)),
('case_type', models.PositiveSmallIntegerField(default=0, choices=[(0, 'Unknown'), (1, 'General'), (2, 'Terror'), (3, 'Narco'), (4, 'Fraud'), (5, 'Slavery'), (6, 'Traffic'), (7, 'RICO'), (8, 'War'), (9, 'Cyber'), (20, 'Other')])),
('created_at', models.DateTimeField(null=True, blank=True)),
('comment', models.CharField(max_length=256, null=True, blank=True)),
],
options={
'verbose_name': 'case',
},
),
]
# hunt.migrations.0002_add_hunts.py
def create_initial_hunts(apps, schema_editor):
if settings.DEBUG:
print('\nContent added')
class Migration(migrations.Migration):
dependencies = [
('hunt', '0001_initial'),
]
operations = [
migrations.RunPython(create_initial_hunts, hints={'schema_editor': 'other'}),
]
問題は、「migrate」コマンドを実行すると、デフォルトのデータベースに接続されているアプリケーションのみが移行されることです。残りのアプリの移行は決して実行されません。 --databaseオプションを使用してそのようなアプリの移行を起動すると、正常に機能します。
移行ごとにデータベースを指定するにはどうすればよいですか?ルータはこれを正確に管理することになっているのではないですか?それとも何か他のものを逃したのですか?
_--database
_でターゲットを指定して、データベースごとにmigrate
を1回実行する必要があります。ルーターを調べて、そのデータベースで実際に実行する移行を確認します。
私はそれが暗黙よりも明示を優先するようにこのように設計されたと思います。たとえば、ワークフローでは、異なるデータベースを異なるタイミングで移行する必要がある場合があります。
ただし、実際に実行された移行を出力から確認することはできません since :
allow_migrate()
がFalse
を返す場合、migrate
をdb
で実行すると、_model_name
_の移行操作は何も通知されずにスキップされます。