指定多个数据库时,Django syncdb 尝试插入重复行
Posted
技术标签:
【中文标题】指定多个数据库时,Django syncdb 尝试插入重复行【英文标题】:Django syncdb trying to insert duplicate rows when multiple databases are specified 【发布时间】:2012-05-16 20:47:20 【问题描述】:我正在为多个数据库配置我的 Django 应用程序,作为权宜之计,我在我的 settings.py 中使用以下配置:
READ_DATABASE =
'ENGINE': 'django.db.backends.mysql',
'NAME': 'thedatabase',
'USER': 'read_only',
'PASSWORD': '',
'OPTIONS':
'init_command': 'SET storage_engine=INNODB'
WRITE_DATABASE =
'ENGINE': 'django.db.backends.mysql',
'NAME': 'thedatabase',
'USER': 'root',
'PASSWORD': '',
'OPTIONS':
'init_command': 'SET storage_engine=INNODB'
DATABASES = 'default': WRITE_DATABASE,
'read': READ_DATABASE
它们指向同一个数据库,以模拟主从对。 read_only
用户,您可能猜到了,只有读取权限。
我的数据库路由器如下所示:
from django.conf import settings
class MasterSlaveRouter(object):
def db_for_read(self, model, **hints):
return 'read'
def db_for_write(self, model, **hints):
return 'default'
def allow_relation(self, db1, db2, **hints):
return True
def allow_syncdb(self, db, model):
return db in ('default',)
运行syncdb时,现在设置超级用户后立即崩溃,并出现错误:
django.db.utils.IntegrityError: (1062, "Duplicate entry 'auth-permission' for key 'app_label'")
未能执行的违规 SQL 是:
INSERT INTO `django_content_type` (`name`, `app_label`, `model`) VALUES (permission, auth, permission)
此错误仅在我的settings.py
中指定第二个读取数据库时发生,当仅存在default
数据库时,syncdb 命令成功完成。
有什么建议可能导致这种情况吗?
编辑: Django 版本是 1.2.3
【问题讨论】:
如何指定DATABASE_ROUTERS
? post_syncdb
好像被触发了两次。
DATABASE_ROUTERS = ['path.to.MasterSlaveRouter']
在我的配置文件中。
好的,你能显示实际的path.to
吗;并尝试将MasterSlaveRouter
放入设置中,然后设置DATABASE_ROUTERS = ['settings.MasterSlaveRouter']
?
路由器肯定被击中 - 我已将 import pdb; pdb.set_trace
添加到 db_for_read/write
方法中验证这一点。断点被击中,路由器的可发现性绝对不是问题。不过感谢您的建议。
是的,我并不是说它没有被使用过。我的意思是导入可能会导致post_syncdb
被绑定多次,因此 contenttypes 想要为 Permission 模型生成 content_type 两次,因此出现错误
【参考方案1】:
经过几个小时的修改,我推断发生这种情况的原因是因为某些 Django 模型(在本例中为 django.contrib.contenttype.models.ContentType
,但也有 django.contrib.site.models.Site
)有自己的 inbuilt caching mechanism。
由于我已经为同一个数据库设置了两个不同的连接,这导致了一个问题,因为在写入连接上写入 ContentType
模型并没有使只读连接的 contenttype
缓存失效.
解决方案是将我的 db_for_read
方法更改为如下所示:
【讨论】:
以上是关于指定多个数据库时,Django syncdb 尝试插入重复行的主要内容,如果未能解决你的问题,请参考以下文章
运行 Django 的 syncdb 时 OSX 10.7.3 上的 Postgresql 套接字错误
运行 Django 的 ./manage.py syncdb 时自动创建管理员用户