2016-02-24 35 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