我正在将Django应用程序从2.2.7升级到3.1.3。该应用程序使用Postgres 12&;psycopg2 2.8.6
我按照说明将所有django.contrib.postgres.fields.JSONField
引用更改为django.db.models.JSONField
,并进行迁移并运行迁移。这不会对我的模式产生任何更改(这很好)
但是,当我执行一个原始查询时,这些jsonb
列的数据会在某个时候以文本形式返回,或者转换为文本。当直接使用Model.objects.get(...)
查询模型时,我没有看到这个问题
import os, django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "big_old_project.settings")
django.setup()
with connection.cursor() as c:
c.execute("select name, data from tbl where name=%s", ("rex",))
print(c.description)
for row in c.fetchall():
for col in row:
print(f"{type(col)} => {col!r}")
(Column(name='name', type_code=1043), Column(name='data', type_code=3802))
<class 'str'> => 'rex'
<class 'str'> => '{"toy": "bone"}'
[编辑]使用原始连接可获得预期结果:
conn = psycopg2.connect("dbname=db user=x password=z")
with conn.cursor() as c:
...
<class 'str'> => 'rex'
<class 'dict'> => {'toy': 'bone'}
尝试“注册”适配器的老把戏是行不通的,无论如何也不需要
import psycopg2.extras
psycopg2.extras.register_json(oid=3802, array_oid=3807, globally=True)
这个应用程序有很多历史,所以可能有什么东西在踩psycopg2的脚?到目前为止,我找不到任何东西,而且我已经把所有与此相关的东西都注释掉了
浏览发行说明没有帮助。我确实使用了其他postgres字段,因此无法从模型中删除对contrib.postgres.fields
的所有引用
任何关于为什么会发生这种情况的想法都将不胜感激
为了补充@Andrew Backer有用的答案,这显然是有意的。从3.1.1 release notes开始:
令人惊讶的是,在bugfix版本中发现了一个API不兼容的变更作为旁白。现在,我将添加
json.loads()
调用,因为正如前面提到的,不能保证::json
解决方案也不会中断谢谢你这篇有用的帖子!我对此错误的解决方案如下所示:
好的,这似乎是他们出于某种原因在Django3.1.1中引入的一个更改,以修复其他一些bug。它从底层连接中注销
jsonb
转换器,这在IMO中很糟糕Django问题:第一个“修复”破坏了这个基本功能,同时拒绝了原始sql的用例,第二个是宣布破坏无效
要解决这个问题,您可以创建自己的原始游标(django不会使用它),或者在原始sql中强制转换字段。至少,直到他们也打破它
相关问题 更多 >
编程相关推荐