我有两个 Postgres 数据库连接,当使用其他非默认 ORM 调用时,视图会失败,但原始视图不会失败。我正在使用 docker 并连接容器并使用 Django 自己的 runserver 命令。在 django 命令或 django shell 中使用 ORM 可以正常工作,但不能在视图中使用。
顺便说一句,这两个数据库实际上都是 Django 项目,但主项目是使用自己的非托管模型直接从另一个项目的数据库读取一些数据。
# settings
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'USER': 'pguser',
'PASSWORD': 'pguser',
'NAME': 'mainproject',
'HOST': 'project-db', # docker container
'PORT': '5432',
},
'external': {
'ENGINE': 'django.db.backends.postgresql',
'USER': 'pguser',
'PASSWORD': 'pguser',
'NAME': 'sideproject',
'HOST': 'side-db', # docker container, attached to same network
'PORT': '5432',
},
}
# My unmanaged model
class MyTestModel(models.Model):
class Meta:
# table does not exist in 'default', but it does exist in 'external'
db_table = 'my_data_table'
managed = False
# my_data_table is very simple it has id field as integer
# and primary key (works out of the box with django)
# it has normal fields only like IntegerField or CharField
# But even if this model is empty then it returns normally the PK field
# My custom command in Main project
# python manage.py mycommand
# ...
def handle(self, *args, **options):
# This works fine and data from external is populated in MyTestModel
data = MyTestModel.objects.using('external').all()
for x in data:
print(x, vars(x))
# My simple view in Main project
class MyView(TemplateView):
# But using example in views.py, random view class:
def get(self, request, *args, **kwargs):
# with raw works
data = MyTestModel.objects.using('external').raw('select * from my_data_table')
for x in data:
print(x, vars(x))
# This does not work
# throws ProgrammingError: relation "my_data_table" does not exist
data = MyTestModel.objects.using('external').all()
for x in data:
print(x, vars(x))
return super().get(request, *args, **kwargs)
因此,在使用 ORM 时,runserver 和views 无法正确生成查询。它不可能是连接错误,因为使用“.raw()”运行命令或视图时有效。
现在有趣的是,如果我将“db_table”更改为两个数据库中常见的内容,那么“django_content_type”ORM“filter()”和“all()”也可以在视图中使用。是的,它实际上从正确的数据库返回数据。因此,如果主项目有 50 种内容类型,而副项目(外部)有 100 种内容类型,它实际上会从外部返回这 100 种内容类型。
我已经尝试了一切,重建docker,直接创建新表到数据库,强制重新加载postgres用户并确保所有权限都是所有者权限和所有权限(无论如何应该没问题,因为命令端可以工作)。我什至尝试使用另一个数据库。
我知道我没有发布完整的设置和我的本地设置,这可以帮助更多地解决这个问题。
但我注意到我在本地安装了 Django Silk,它捕获请求并尝试分析调用的数据库查询。看起来它可能加载得太早或者它不喜欢外部数据库。但是从已安装的应用程序中禁用 Django Silk 并删除它的中间件就解决了这个问题。
我有同样的问题,但我使用sqlite db说表不存在