我有一個這樣的資料庫表:
-------------------------------------------------------------
| id | res_id | path | overrides |
|-------------------------------------------------------------|
| 1 | res_1 | res_1 | {"enabled": True} |
| 2 | res_1.1 | res_1.res_1.1 | {"enabled": False}|
| 3 | res_1.2 | res_1.res_1.2 | {"enabled": False}|
| 4 | res_1.1.1 | res_1.res_1.1.res_1.1.1| {"enabled": False}|
-------------------------------------------------------------
用于設定繼承的overrides斷點。所以,如果我查詢res_1.1.1m 我通常也會得到資源 1 和 2,因為繼承。但是現在,存在"enabled": Truein1并且它不會在任何地方繼承,因此查詢將只回傳 2 和 4。
問題是,如何過濾掉存在的overrides物件"enabled": True?我已經嘗試過,例如:.filter(MyModel.overrides["enabled"] is not True),這似乎不起作用。
我也嘗試過使用字典方法get(),values()和keys(),但它們給了我一個錯誤,例如AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with MyModel.overrides has an attribute 'get'。-field中的
欄位。overridesJSONB
uj5u.com熱心網友回復:
您在這里缺少兩件事。
首先,.filter(col is not True)不能用 SQLAlchemy 編譯,我建議你使用.filter(col == False)or .filter(col.is_(False))。
然后要訪問 JSONB 字典中的值,您需要將其轉換為 SQL 型別,例如使用.as_boolean().
將兩者放在一起,我們得到:
stmt = (
select(MyModel)
.filter(MyModel.overrides["enabled"].as_boolean() == False)
)
完整的腳本演示:
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
metadata_obj = sa.MetaData()
t = sa.Table(
"t72632977",
metadata_obj,
sa.Column("id", sa.Integer, primary_key=True),
sa.Column("res_id", sa.String),
sa.Column("path", sa.String),
sa.Column("overrides", postgresql.JSONB),
)
engine = sa.create_engine(
"postgresql psycopg2://postgres:postgres@localhost:5432/postgres",
echo=True,
future=True,
)
metadata_obj.create_all(engine)
with engine.begin() as con:
con.execute(
sa.insert(t),
[
{
"res_id": "res_1",
"path": "res_1",
"overrides": {"enabled": True},
},
{
"res_id": "res_1.1",
"path": "res_1.res_1.1",
"overrides": {"enabled": False},
},
{
"res_id": "res_1.2",
"path": "res_1.res_1.2",
"overrides": {"enabled": False},
},
{
"res_id": "res_1.1.1",
"path": "res_1.res_1.1.res_1.1.1",
"overrides": {"enabled": False},
},
],
)
with engine.connect() as con:
r = con.execute(
sa.select(t).filter(t.c.overrides["enabled"].as_boolean() == False)
)
print(r.all())
# emits
# SELECT t72632977.id, t72632977.res_id, t72632977.path, t72632977.overrides
# FROM t72632977
# WHERE CAST((t72632977.overrides ->> %(overrides_1)s) AS BOOLEAN) = false
# returns
# [
# (2, 'res_1.1', 'res_1.res_1.1', {'enabled': False}),
# (3, 'res_1.2', 'res_1.res_1.2' , {'enabled': False}),
# (4, 'res_1.1.1', 'res_1.res_1.1.res_1.1.1', {'enabled': False}),
# ]
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/491943.html
