Возможно ли использование нескольких баз данных и Юга?
Мой текущий проект расширяется с помощью географического материала, поэтому я пытаюсь интегрировать 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.
Ответы
Ответ 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" для южного приложения. Тогда ваша миграция должна прекратиться.