Django 'geo_db_type' 多个数据库的 AttributeError
Django 'geo_db_type' AttributeError with Multiple Databases
背景
我将 Django 与多个数据库一起使用:我有一个 Postgres 数据库和一个 mysql 数据库(充满了我正在慢慢转换到 Postgres 的遗留数据)。
我最近引入了 GeoDjango(以 django.contrib.gis 的形式),带有用于存储 lat/lng 信息的 postgis 扩展作为一个点。该应用程序本身似乎 运行 没问题。我可以很好地从 mysql 数据库和 postgres 数据库访问信息。我什至可以利用新的点字段,这意味着(对我来说)'gis' 东西正在工作和配置。
问题
当我尝试 运行 测试时出现问题。我收到以下错误:
AttributeError: 'DatabaseOperations' object has no attribute 'geo_db_type'
我相信这发生在 mysql 数据库上,因为我首先收到提示,指出 test_db postgress 数据库存在并且需要删除并重新创建。我输入 'yes',它完成了它的工作,然后给我关于 test_mysql 数据库的相同提示。当我回答 'yes' 时,出现错误。
我的旧应用程序的模型不使用任何新字段;导入是 django.db。所以我不明白为什么测试认为我需要对 mysql 数据库进行地理空间操作。
我试过的
1) 注释掉 MySQL 数据库
这确实有效;测试 运行 很好。但是,这不是一个好的解决方案,原因很明显...
2) 将 MySQL 的数据库引擎更改为使用 'django.contrib.gis.db.backends.mysql'
执行此操作时出现不同的错误:
django.db.utils.OperationalError: (1071, 'Specified key was too long; max key length is 767 bytes')
我猜这是由于我的旧模型中某处的复合键所致。这真的不应该成为问题,我不认为,因为我实际上 运行 在后台运行 MariaDB 10.0.31。此外,django.db.backends.mysql 不会抱怨它。所以我想知道 django.contrib.gis.db.backends.mysql 是否有点过时(因为 MySQL 似乎空间支持有限)。
我不明白为什么测试数据库报错,但应用程序似乎正常工作。
提前感谢您提供的任何帮助!我完全被难住了。
支持信息
我的数据库配置如下所示:
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': os.environ.get('PG_DB_NAME'),
'USER': os.environ.get('PG_DB_USER'),
'PASSWORD': os.environ.get('PG_DB_PASS'),
'HOST': os.environ.get('PG_DB_HOST'),
'PORT': '',
},
'legacy': {
'ENGINE': 'django.db.backends.mysql',
'NAME': os.environ.get('MY_DB_NAME'),
'USER': os.environ.get('MY_DB_USER'),
'PASSWORD': os.environ.get('MY_DB_PASS'),
'HOST': os.environ.get('MY_DB_HOST'),
'PORT': '',
},
}
我有一个数据库路由器:
class LegacyRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label == 'legacy':
return 'legacy'
return 'default'
编辑:Hacky 解决方法
因此,经过反复试验后,我发现我可以通过使用单个 postgresql 数据库进行测试来解决这个问题。我通过添加第二个设置文件并在测试时引用它来完成此操作。
from .settings import *
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': os.environ.get('TEST_DB_NAME'),
'USER': os.environ.get('TEST_DB_USER'),
'PASSWORD': os.environ.get('TEST_DB_PASS'),
'HOST': os.environ.get('TEST_DB_HOST'),
},
}
DATABASE_ROUTERS = []
在测试时会调用它,例如:
python manage.py test --settings=<module>.test-settings
这对我有用,因为我的遗留数据没有特定于数据库的内容,所以我没有理由不能使用 postgres 进行测试。希望这对其他人有帮助。
编辑:修复
问题出在数据库路由器中。除 'legacy' 应用程序之外的所有应用程序都被路由到 'default' 数据库(预期),而所有应用程序加上 'legacy' 应用程序都被路由到 'legacy' 数据库。
要修复,我需要一个 allow_migrate 函数。这是我的制作方法:
def allow_migrate(self, db, app_label, model_name=None, **hints):
# Legacy app should only be in legacy database
# Return true if app is legacy and database is legacy
if app_label == 'legacy':
return db == 'legacy'
# Legacy database should only contain legacy app
# Return true if app is not legacy and database not legacy
elif app_label != 'legacy':
return db != 'legacy'
else:
return None
回答
问题出在数据库路由器中。除 'legacy' 应用程序之外的所有应用程序都被路由到 'default' 数据库(预期),而所有应用程序加上 'legacy' 应用程序都被路由到 'legacy' 数据库。
为了解决这个问题,我需要一个 allow_migrate 函数来阻止 'legacy' 应用程序以外的所有应用程序迁移到 'legacy' 数据库中。有关详细信息,请参阅我的问题中的编辑。
背景
我将 Django 与多个数据库一起使用:我有一个 Postgres 数据库和一个 mysql 数据库(充满了我正在慢慢转换到 Postgres 的遗留数据)。
我最近引入了 GeoDjango(以 django.contrib.gis 的形式),带有用于存储 lat/lng 信息的 postgis 扩展作为一个点。该应用程序本身似乎 运行 没问题。我可以很好地从 mysql 数据库和 postgres 数据库访问信息。我什至可以利用新的点字段,这意味着(对我来说)'gis' 东西正在工作和配置。
问题
当我尝试 运行 测试时出现问题。我收到以下错误:
AttributeError: 'DatabaseOperations' object has no attribute 'geo_db_type'
我相信这发生在 mysql 数据库上,因为我首先收到提示,指出 test_db postgress 数据库存在并且需要删除并重新创建。我输入 'yes',它完成了它的工作,然后给我关于 test_mysql 数据库的相同提示。当我回答 'yes' 时,出现错误。
我的旧应用程序的模型不使用任何新字段;导入是 django.db。所以我不明白为什么测试认为我需要对 mysql 数据库进行地理空间操作。
我试过的
1) 注释掉 MySQL 数据库
这确实有效;测试 运行 很好。但是,这不是一个好的解决方案,原因很明显...
2) 将 MySQL 的数据库引擎更改为使用 'django.contrib.gis.db.backends.mysql'
执行此操作时出现不同的错误:
django.db.utils.OperationalError: (1071, 'Specified key was too long; max key length is 767 bytes')
我猜这是由于我的旧模型中某处的复合键所致。这真的不应该成为问题,我不认为,因为我实际上 运行 在后台运行 MariaDB 10.0.31。此外,django.db.backends.mysql 不会抱怨它。所以我想知道 django.contrib.gis.db.backends.mysql 是否有点过时(因为 MySQL 似乎空间支持有限)。
我不明白为什么测试数据库报错,但应用程序似乎正常工作。
提前感谢您提供的任何帮助!我完全被难住了。
支持信息
我的数据库配置如下所示:
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': os.environ.get('PG_DB_NAME'),
'USER': os.environ.get('PG_DB_USER'),
'PASSWORD': os.environ.get('PG_DB_PASS'),
'HOST': os.environ.get('PG_DB_HOST'),
'PORT': '',
},
'legacy': {
'ENGINE': 'django.db.backends.mysql',
'NAME': os.environ.get('MY_DB_NAME'),
'USER': os.environ.get('MY_DB_USER'),
'PASSWORD': os.environ.get('MY_DB_PASS'),
'HOST': os.environ.get('MY_DB_HOST'),
'PORT': '',
},
}
我有一个数据库路由器:
class LegacyRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label == 'legacy':
return 'legacy'
return 'default'
编辑:Hacky 解决方法
因此,经过反复试验后,我发现我可以通过使用单个 postgresql 数据库进行测试来解决这个问题。我通过添加第二个设置文件并在测试时引用它来完成此操作。
from .settings import *
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': os.environ.get('TEST_DB_NAME'),
'USER': os.environ.get('TEST_DB_USER'),
'PASSWORD': os.environ.get('TEST_DB_PASS'),
'HOST': os.environ.get('TEST_DB_HOST'),
},
}
DATABASE_ROUTERS = []
在测试时会调用它,例如:
python manage.py test --settings=<module>.test-settings
这对我有用,因为我的遗留数据没有特定于数据库的内容,所以我没有理由不能使用 postgres 进行测试。希望这对其他人有帮助。
编辑:修复
问题出在数据库路由器中。除 'legacy' 应用程序之外的所有应用程序都被路由到 'default' 数据库(预期),而所有应用程序加上 'legacy' 应用程序都被路由到 'legacy' 数据库。
要修复,我需要一个 allow_migrate 函数。这是我的制作方法:
def allow_migrate(self, db, app_label, model_name=None, **hints):
# Legacy app should only be in legacy database
# Return true if app is legacy and database is legacy
if app_label == 'legacy':
return db == 'legacy'
# Legacy database should only contain legacy app
# Return true if app is not legacy and database not legacy
elif app_label != 'legacy':
return db != 'legacy'
else:
return None
回答
问题出在数据库路由器中。除 'legacy' 应用程序之外的所有应用程序都被路由到 'default' 数据库(预期),而所有应用程序加上 'legacy' 应用程序都被路由到 'legacy' 数据库。
为了解决这个问题,我需要一个 allow_migrate 函数来阻止 'legacy' 应用程序以外的所有应用程序迁移到 'legacy' 数据库中。有关详细信息,请参阅我的问题中的编辑。