Подтвердить что ты не робот

Возможно ли использование нескольких баз данных и Юга?

Мой текущий проект расширяется с помощью географического материала, поэтому я пытаюсь интегрировать GeoDjango и импортировать некоторые шейп файлы для начинающих. Моя настройка состоит из следующих элементов:

  • MySQL 5.0 как база данных по умолчанию, ранее единственная база данных.
  • Spatialite как база данных "gis", должна использоваться только для импорта областей из шейп файлов
  • South используется во всем проекте

Теперь я создал модель GeoDjango в новом приложении для своих областей. Как обычно, я выполнил ./manage.py schemamigration --initial, и когда я попытался сделать ./manage.py migrate $my_new_app --database="gis", он потерпел неудачу с django.db.utils.DatabaseError: no such table: south_migrationhistory, что, я думаю, правильно, поскольку south_migrationhistory находится в моей основной базе данных.

Есть ли у кого-нибудь опыт работы с такими настройками и может помочь мне?

EDIT: Я изменил название, так как понял, что этот вопрос не является специфическим для GeoDjango.

4b9b3361

Ответ 1

Моя улучшенная душа:

Чтобы создать таблицу south_migrationhistory в другой базе данных:

./manage.py syncdb --database="my_db_name_for_apps"

Теперь вы можете использовать стандарт:

./manage.py migrate my_app

Вот мой фактический db_router.py

# -*- coding: UTF-8 -*-
apps =['app1', 'app2' ]    
db_name = 'my_db_name_for_apps'

class sh_router(object):
    """A router to control all database operations on models from applications in apps"""

    def db_for_read(self, model, **hints):
        """Point all operations on apps models to db_name"""
        if model._meta.app_label in apps :
            return db_name
        return None

    def db_for_write(self, model, **hints):
        """Point all operations on apps models to db_name"""
        if model._meta.app_label in apps:
            return db_name
        return None

    def allow_relation(self, obj1, obj2, **hints):
        """Allow any relation if a model in apps is involved"""
        if obj1._meta.app_label in apps or obj2._meta.app_label in apps:
            return True
        return None

    def allow_syncdb(self, db, model):
        """Make sure the apps only appears on the db_name db"""
        if model._meta.app_label in ['south']:
            return True
        if db == db_name:
            return model._meta.app_label in apps
        elif model._meta.app_label in apps:
            return False
        return None

Ответ 2

Я нашел все ответы несколько неточными, поэтому вот краткое изложение.

Прежде всего, каждый должен, конечно, прочитать несколько строк о нескольких базах данных в документации Юга:)

Способ сделать это - вручную отредактировать файлы миграции, чтобы указать на правильную базу данных. Самый простой способ - добавить это в начало всех файлов:

from south.db import dbs
db = dbs['name_of_you_nondefault_db']

Основная причина заключается в том, что Юг не выбирает имя базы данных из ваших маршрутизаторов базы данных. Эта функция просто не реализована и, вероятно, никогда не будет с приходом Django 1.7.

Но чтобы все началось, запустите:

python manage.py syncdb

Теперь у вас есть таблица статистики south_migration. Затем, чтобы перенести вашу специальную базу данных, выполните следующие действия:

python manage.py migrate

История south_migration не будет создана в каждой базе данных, только по умолчанию. Таким образом, история миграции может быть централизована.

Несколько баз данных с разными копиями одного и того же приложения

Если у вас есть несколько баз данных, которые вам необходимо перенести в одно и то же приложение внутри, вы не должны использовать уникальную историю миграции.

Вместо этого создайте yv_migrationhistory следующим образом:

python manage.py sql south | PGOPTIONS="-c search_path=NAME_OF_YOUR_SCHEMA_TO_CREATE_IN" python manage.py dbshell --database=name_of_you_nondefault_db

Теперь вы должны запустить миграцию, указав BOTH app_label и базу данных, чтобы получить версию south_migration.

python manage.py migrate name_of_app --database=name_of_you_nondefault_db

Ответ 3

В моем db_router.py файле я просто раскомментирую приложение 'south' в списке моих приложений. Я запускаю syncdb для создания таблицы south_migrationhistory в базе данных otherdb.

./manage.py syncdb --database="otherdb"

И следующий комментарий снова в приложении 'south' в списке моих приложений.

Теперь вы можете использовать стандартный

./manage.py migrate my_app --database="otherdb"

Вот мой db_router.py

#-*- coding: UTF-8 -*-

apps =['app1',
     'app2',
     'south', # <<<---------------- Comment / Uncomment here
   ]

db_name = 'otherdb'

class sh_router(object):
"""A router to control all database operations on models from applications in apps"""

  def db_for_read(self, model, **hints):
    """Point all operations on apps models to db_name"""
    if model._meta.app_label in apps :
        return db_name
    return None

  def db_for_write(self, model, **hints):
    """Point all operations on apps models to db_name"""
    if model._meta.app_label in apps:
        return db_name
    return None

  def allow_relation(self, obj1, obj2, **hints):
    """Allow any relation if a model in apps is involved"""
    if obj1._meta.app_label in apps or obj2._meta.app_label in apps:
        return True
    return None

  def allow_syncdb(self, db, model):
    """Make sure the apps only appears on the db_name db"""
    if db == db_name:
        return model._meta.app_label in apps
    elif model._meta.app_label in apps:
        return False
    return None

Ответ 4

Как сказал Томаш, вам нужно синхронизировать свой "gis" db, чтобы создать все необходимые таблицы, в том числе south_migrationhistory.

./manage.py syncdb --database=gis

Ответ 5

Похоже, что Django 1.7 имеет allow_migrate() в своем классе маршрутизатора базы данных, чтобы решить эту проблему.

Для более ранних Djangos:

  • вам нужна south_migrationhistory в любом db, где вы хотите выполнять миграцию.
  • выполните регулярную syncdb, чтобы поместить все обычные таблицы auth_ * и т.д. в default db
  • который поместит south_migrationhistory в default
  • не выполняйте syncdb --database=other, который будет дублировать все auth_ * и т.д. таблицы в other
  • скопируйте таблицу south_migrationhistory с default на other, например.

    sqlite3 main.sqlite ".sc south_migrationhistory" | sqlite3 other.sqlite

    или эквивалентную команду pg_dump или что-то еще

  • затем используйте migrate --database=other

По крайней мере, это все в нужном месте, пока вы не перейдете на 1.7: -)

Ответ 6

Я знаю, что поток старый, но у меня была такая же проблема, и Google получил мне эту тему.

Итак, сначала вам нужно изменить способ переноса данных:

    def forwards(self, orm):
    "Write your forwards methods here."                               
        obj = orm.Obj()
        obj.name = 'my name'
        obj.save(using=db.db_alias)

Переменная db.db_alias содержит имя используемого db, поэтому вам нужно будет сделать все с помощью usgin и использовать db.db_alias в качестве имени db.

то вы выполняете миграцию с помощью . /mange migrate App --database = DB_NAME

в случае схемамирования просто используйте функцию db.function, например, юг.

Ответ 7

Вероятно, вы хотите иметь south_migrationhistory в обеих базах данных, поэтому syncdb для "gist" для южного приложения. Тогда ваша миграция должна прекратиться.