2016-02-24 78 views
8

我很難創建數據遷移。我爲我的應用程序使用兩個數據庫。我在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一次,指定目標爲--database。每次它將諮詢您的路由器,以查看哪些遷移實際上在該數據庫上執行。

我猜測它被設計成這種方式來支持對隱含性的顯式性。例如,您的工作流可能需要您在不同的時間遷移不同的數據庫。

注意,雖然,你將無法從其中實際執行遷移輸出告訴,since

遷移將只是默默不上一個模型此返回False執行任何操作。

+1

謝謝,我結束了這一切。 –

+3

爲什麼Django在提供'DATABASE_ROUTERS'時不支持這個多個數據庫問題?這很奇怪。 – dannydedog