【问题标题】:Pass whole row to DB function as an argument SQLAlchemy将整行作为参数传递给 DB 函数 SQLAlchemy
【发布时间】:2022-12-03 06:02:58
【问题描述】:

我需要使用以下 SQL 表达式来实现SQLAlchemy 1.4.41,Postgres 13.6

SELECT book.name,
       my_func(book) AS func_result
FROM book WHERE book.name = 'The Adventures of Tom Sawyer';

有没有办法实现这样的 SQL 表达式?

功能如下,我不应该改变它:

create function my_func(table_row anyelement) returns json

我假设将 Book 传递给 func.my_func 是不正确的,因为 SQLAlchemy 将其解压缩到 Book 属性列表(例如 book.id, book.name, book.total_pages

from db.models import Book
from sqlalchemy import func, select

function = func.my_func(Book)
query = select(Book.name, function).where(Book.name == 'The Adventures of Tom Sawyer')

【问题讨论】:

    标签: python sql sqlalchemy


    【解决方案1】:

    在 PostgreSQL 中,您可以通过将行对象传递给函数来完成此操作。例如,row_to_json 是一个接受row 并返回 JSON 的函数,因此给定此表

                                        Table "public.users"
          Column       │       Type        │ Collation │ Nullable │           Default            
    ═══════════════════╪═══════════════════╪═══════════╪══════════╪══════════════════════════════
     id                │ integer           │           │ not null │ generated always as identity
     name              │ character varying │           │          │ 
     registration_date │ date              │           │          │ 
    

    这个查询

    select name, row_to_json(users) from users;
    

    可以返回

     name  │                       row_to_json                        
    ═══════╪══════════════════════════════════════════════════════════
     Alice │ {"id":1,"name":"Alice","registration_date":"2022-10-27"}
     Bob   │ {"id":2,"name":"Bob","registration_date":"2022-10-27"}
    

    将其转换为 SQLAlchemy,如果您仅传递模型下表中的列(因此没有关系),则可以使用 FromClause.table_valued 作为快捷方式。

    q = sa.select(User.name, sa.func.row_to_json(User.__table__.table_valued()))
    

    如果您确实需要关系中的值,或者只需要表字段的子集,则需要使用子查询来指定它们*:

    subq = sa.select(User.id, User.name).subquery()                                                                           
    q = sa.select(sa.func.row_to_json(subq.table_valued()))
    

    *这部分答案的灵感来源于this answer by Anatoly Ressin

    【讨论】:

      猜你喜欢
      • 2013-01-27
      • 2021-04-13
      • 1970-01-01
      • 1970-01-01
      • 2021-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多