繁体   English   中英

SQLAlchemy 通过 JSON 子字段加入

[英]SQLAlchemy join through JSON sub field

I have an existing SQLAlchemy model that is supposed to have a relation to another model, however the connecting point there is sadly a (sub)field of a JSON PostgreSQL column.

因此,假设一个表“类别”是:

id(bigint) | name(string)
-------------------------
         5 | Comics

...第二个表“英雄”是:

id(bigint) | name(string) | info(JSON)
-------------------------------------------------------------
         2 | Tranquility  | {"category_id":5, "genre_id": 17}

我将如何在 python SQLAlchemy&PostgreSQL9.5 中通过heroinfo["category_id"] category hero上的类别以获得以下结果?

id(bigint) | name(string) | category_name | info(JSON)
-------------------------------------------------------------
         2 | Tranquility  | Comics        | {"category_id":5, "genre_id": 17}

根据这个答案,我知道 PostgreSQL 本身有可能发生这样的事情

https://dba.stackexchange.com/a/83935http://sqlfiddle.com/#!15/226c33/1

并且可能需要一些技巧来铸造或绕过默认方式
json 字段的 sqlalchemy 过滤器中所述

注意:请注意,我不能更改 DB 结构,也不能更改 model 的现有部分,而且我也不是在寻找我已经知道的双重查询绕过。

您可以使用json_to_record创建一个内存表,然后加入该表。

https://www.postgresql.org/docs/9.4/functions-json.html

另一个问题已经回答了这个问题,但使用json_to_recordset作为数据是对象列表https://stackoverflow.com/a/31333794/3358570

这里是 SQL 您可以根据需要转换为 sqlalchemy,

SELECT hero.id as hero_id, hero.name as name, d.name as category_name, info
FROM hero,
     json_to_record(hero.info) AS x(category_id int)
         JOIN category d on d.id = category_id

这里 db fiddle 为你https://www.db-fiddle.com/f/7ops4KXVDF6KpY5JZau7vG/1

另一种更简单的方法是在 join 中访问 JSON 值并输入种姓category_id

SELECT hero.id       AS hero_id,
       hero.name     AS hero_name,
       category.name AS category_name,
       category.id   AS category_id,
       hero.info     AS hero_info
FROM hero
     JOIN category ON category.id = CAST(hero.info ->> 'category_id' AS INTEGER)

等效的 qalchemy 会变成,

category_id = cast(Hero.info.op("->>")("category_id"), Integer)
query = (db.session.query(Hero.id, Hero.name, Category.name, Category.id, Hero.info)
         .join(Category, Category.id == category_id))
data = query.all()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM