簡體   English   中英

Postgres SQLAlchemy 附加到現有的 jsonb 記錄

[英]Postgres SQLAlchemy appending to existing jsonb record

我有一個帶有 jsonb 字段data的 postgres 數據庫。

我希望能夠使用 sqlalchemy 附加到字段中的項目數組。

以表格為例:

ID 數據 姓名
1 [{“喬恩”:{“年齡”:4}},{“簡”:{“年齡”:7}}] 保羅
2 [{“綠柱石”:{“年齡”:3}},{“維克多”:{“年齡”:9}}] 戴夫

要在 postgres 中執行此操作,我可以像這樣使用連接:

UPDATE "test" SET "data" = "data" || '[{"beryl": {"age": 3}}, {"victor": {"age": 9}}]' ::jsonb
WHERE "name"='paul';

給予:

ID 數據 姓名
1 [{“喬恩”:{“年齡”:4}},{“簡”:{“年齡”:7}},{“綠柱石”:{“年齡”:3}},{“維克多”:{“年齡”:9}}] 保羅

我試過在 sqlalchemy 中使用 jsonb_insert,但我不清楚如何設置路徑。

我不想在特定鍵處添加數組,但想添加到現有數組中。

編輯

以下將另一個數組嵌套在我現有的數組中,即['A', 'B']的形式變為['A','B',['C','D']] 我希望這是['A','B','C','D']

func.jsonb_insert(
    cast(TestObj.data, JSONB), "{-1}", cast(new_records, JSONB), True
)

編輯 2

使用synchronize_session="fetch"並在循環中添加記錄是可行的,但我不確定它對於很多記錄是否非常有效。

感謝任何關於如何改進這一點的想法。

for rec in new_records:
    session.query(TestObj).filter(TestObj.name == "paul").update(
        {
            "data": func.jsonb_insert(
                cast(TestObj.data, JSONB), "{-1}", cast(rec, JSONB), True
            )
        },
        synchronize_session="fetch",
    )

完整示例代碼:

import os
from sqlalchemy.dialects.postgresql import JSON, JSONB
from sqlalchemy import func, cast
import sqlalchemy as sa
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
import urllib
from sqlalchemy.dialects import postgresql
from dotenv import load_dotenv

load_dotenv()

user = urllib.parse.quote_plus(os.environ.get("DB_USER"))
passwd = urllib.parse.quote_plus(os.environ.get("DB_PW"))

DB_URL = "postgresql://{}:{}@{}:{}/{}".format(
    user,
    passwd,
    os.environ.get("DB_HOST"),
    os.environ.get("DB_PORT"),
    os.environ.get("DB_NAME"),
)

engine = sa.create_engine(DB_URL)
Session = sessionmaker(bind=engine, autoflush=True)

session = Session()

Base = declarative_base()


class TestObj(Base):
    __tablename__ = "test"
    __table_args__ = {"autoload_with": engine, "schema": "public"}



initial_data = [
    {
        "jon": {"age": 4},
    },
    {"jane": {"age": 7}},
]

newentry = {"data": initial_data, "name": "paul"}

stmt = postgresql.insert(TestObj).values(newentry)
result = session.execute(stmt)
session.commit()


new_records = [{"bob": {"age": 10}}, {"billy": {"age": 10}}]


for rec in new_records:
    session.query(TestObj).filter(TestObj.name == "paul").update(
        {
            "data": func.jsonb_insert(
                cast(TestObj.data, JSONB), "{-1}", cast(rec, JSONB), True
            )
        },
        synchronize_session="fetch",
    )

session.commit()




在 SQLAlchemy 中,SQL || 運算符是 Python +運算符。 我在這個 Github issue中找到了這些信息。

附加到您的示例的現有 JSONB 數組應該類似於(未經測試):

new_records = [{"bob": {"age": 10}}, {"billy": {"age": 10}}]

stmt = (
    sa.update(TestObj)
    .filter_by(name="paul")
    .values(data=TestObj.data + new_records)  # concatenate existing data with new records
)
session.execute(stmt)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM