2016-02-24 14 views
8

データ移行の作成には苦労します。私は自分のアプリに2つのデータベースを使用しています。 settings.pyにデータベースを設定し、Django docsのようなルータも作成しました。ここで複数のデータベースを使用したDjangoの移行

# 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 

は、それらのアプリケーションの一つのモデルと移行です:

# 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'}), 
    ] 

問題がある: 私は、コマンドを「移行」を実行すると、データベースをデフォルトに接続されているアプリケーションのみが移行されます。残りのアプリケーションの移行は決して実行されません。私が--databaseオプションを使ってそのようなアプリケーションのためにマイグレーションを起動すると、正常に動作します。

移行ごとにデータベースを指定する方法を教えてください。ルータがこれを正確に管理することになっていないのでしょうか?それとも私は何かを逃した?

答えて

10

データベースごとにmigrateを1回実行し、ターゲットを--databaseで指定する必要があります。ルータごとに、そのデータベースで実際に実行する移行を確認するたびに参照します。

私はそれが暗示よりも明白になるようにこの方法で設計されたと推測しています。たとえば、ワークフローによって、異なる時間に異なるデータベースを移行する必要が生じる場合があります。

注意、しかし、あなたは、移行が実際に行われた出力から知ることができないことをsince

ただ黙って、これは Falseを返すためのモデル上の任意の操作を実行しません

移行。

+1

ありがとう、私はこれを正確にやり終えました。 –

+3

なぜDjangoは 'DATABASE_ROUTERS'を提供しているのに、この複数のDBの問題をサポートしていませんか?これはおかしい。 – dannydedog

関連する問題