2016-02-24 28 views
8

Tôi gặp khó khăn trong việc tạo dữ liệu di chuyển. Tôi sử dụng hai cơ sở dữ liệu cho các ứng dụng của mình. Tôi cấu hình cơ sở dữ liệu trong settings.py và cũng tạo ra một bộ định tuyến như trong Django docs.Di chuyển Django với nhiều cơ sở dữ liệu

# 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 

Dưới đây là mô hình và di cư của một trong những ứng dụng:

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

Vấn đề là: Khi tôi chạy "di chuyển" lệnh, chỉ các ứng dụng kết nối với cơ sở dữ liệu mặc định được di chuyển. Các di chuyển trong phần còn lại của các ứng dụng không bao giờ chạy. Nếu tôi khởi động di chuyển cho một ứng dụng như vậy với tùy chọn --database - nó hoạt động tốt.

Tôi làm cách nào để chỉ định cơ sở dữ liệu cho mỗi lần di chuyển? Router không phải quản lý chính xác điều này sao? Hoặc tôi đã bỏ lỡ điều gì khác?

Trả lời

10

Bạn phải chạy migrate một lần cho mỗi cơ sở dữ liệu, chỉ định mục tiêu với --database. Mỗi lần nó sẽ tham khảo bộ định tuyến của bạn để xem việc di chuyển nào thực sự thực hiện trên cơ sở dữ liệu đó.

Tôi đoán nó được thiết kế theo cách này để ủng hộ sự chứng kiến ​​về nhân chứng. Ví dụ, quy trình làm việc của bạn có thể yêu cầu bạn di chuyển các cơ sở dữ liệu khác nhau vào các thời điểm khác nhau.

Lưu ý, mặc dù, rằng bạn sẽ không có thể cho biết từ đầu ra mà di cư đã thực sự thực hiện, since:

di cư sẽ chỉ lặng lẽ không thực hiện bất kỳ hoạt động trên một mô hình mà này trả False .

+1

Cảm ơn, tôi đã kết thúc chính xác việc này. –

+3

Tại sao Django không hỗ trợ vấn đề này nhiều DB, khi họ cung cấp 'DATABASE_ROUTERS'? Điều này thật kỳ lạ. – dannydedog

Các vấn đề liên quan