我目前的项目正在扩展地理位置,因此我正在尝试集成GeoDjango并为初学者导入一些shapefile。我的设置包括以下内容:
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
在我的主数据库中。
有没有人对此类设置有任何经验并可以帮助我?
编辑:我已经更改了标题,因为我意识到这个问题实际上并不是特定于GeoDjango的。
答案 0 :(得分:9)
我的灵魂得到了改善:
在另一个数据库中创建表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
答案 1 :(得分:9)
我发现所有答案都有些不准确,因此,这是一个总结。
首先,每个人当然应该阅读the South documentation中关于多个数据库的极少数几行:)
执行此操作的方法是手动编辑迁移文件以指向正确的数据库。最简单的方法是将其添加到所有文件的顶部:
from south.db import dbs
db = dbs['name_of_you_nondefault_db']
基本原因是South没有从数据库路由器中获取数据库的名称。这个功能根本没有实现,可能永远不会出现Django 1.7。
但要开始工作,请运行:
python manage.py syncdb
现在,你有了south_migrationhistory表。然后要迁移您的特殊数据库,请执行以下操作:
python manage.py migrate
south_migrationhistory将 NOT 在每个数据库中创建,只有默认数据库。因此,迁移历史可以保持集中。
如果您需要在同一个应用程序中迁移多个数据库,则不应使用单一迁移历史记录。
相反,像这样创建south_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_migrationhistory。
python manage.py migrate name_of_app --database=name_of_you_nondefault_db
答案 2 :(得分:5)
在我的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
答案 3 :(得分:1)
正如Tomasz所说,你必须同步dbdb你的“gis”数据库,以便创建所有必需的表,包括south_migrationhistory。
./manage.py syncdb --database=gis
答案 4 :(得分:1)
似乎Django 1.7在其数据库路由器类中有allow_migrate()来解决这个问题。
对于早期的Djangos:
syncdb
将所有常规auth_ *等表放在default
db 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: - )
答案 5 :(得分:0)
我知道线程已经过时了,但是我遇到了同样的问题,谷歌给了我那个帖子。
首先,您需要更改数据迁移的方式:
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
在schemamigration的情况下,直接使用db.function就像南方一样。
答案 6 :(得分:-2)
您可能希望在两个数据库中都使用south_migrationhistory,因此对于南应用程序,syncdb为“gist”。然后你的迁移就可以了。