首页 > 解决方案 > SQLAlchemy / PostgreSQL 无法确定参数 jsonb[] 的类型

问题描述

我是 SQLAlchemy 的第一次用户,它与 PostgreSQL、FastAPI 和数据库库一起使用。我无法将工作的原始查询转换为 SQLAlchemy 方法,特别是在将列类型确定为jsonb[]并将其包含在json_agg函数中时。我正在使用sqlalchemy_utils类型转换JSONJSONBto SQL

我试图复制的原始查询。

SELECT pr.id, pr.name, json_agg(f) as features FROM projects pr
LEFT JOIN features f ON f.project_id = pr.id
WHERE pr.id IN ('1')
GROUP BY(pr.id);

我通过使用上面我试图在 SQLAlchemy 中复制的查询得到的目标响应

[
    {
        "id": "c7b0af60-3db4-4f07-a397-ee5d8123c88e",
        "name": "Test Name",
        "features": [
            {
                "id": "b5c441f8-79b8-452b-9a42-6c7fc976ca2b",
                "name": "Another Test Name",
                "created_at": "2021-02-01T20:51:26.998+00:00",
                "finished_at": "2021-02-17T20:51:26+00:00",
                "project_id": "c7b0af60-3db4-4f07-a397-ee5d8123c88e",
                "items": null
            },
            {
                "id": "4f03a7f0-eb32-4aae-84aa-678984b46132",
                "name": "Yet Another Test Name",
                "created_at": "2021-02-01T20:51:26.998+00:00",
                "finished_at": "2021-02-20T20:51:26+00:00",
                "project_id": "c7b0af60-3db4-4f07-a397-ee5d8123c88e",
                "items": null
            },
            {
                "id": "7a81da18-409a-4d1d-85cc-308b5c58b5e8",
                "name": "Test Name",
                "created_at": "2021-02-01T18:27:42.146+00:00",
                "finished_at": "2021-03-05T18:27:42+00:00",
                "project_id": "c7b0af60-3db4-4f07-a397-ee5d8123c88e",
                "items": [
                    {
                        "id": "8672001a-833c-4600-bc3b-025ed6451f05",
                        "name": "Test Name",
                        "type": "Test Type",
                        "s3_link": null
                    }
                ]
            }
        ]
    }
]

下面是我的表以及我如何使用 SQLAlchemy 定义它们。

from sqlalchemy import Table, Column, String, ForeignKey
from sqlalchemy.dialects.postgresql import UUID, ARRAY, TIMESTAMP, JSONB
from db.db import metadata

features = Table('features', metadata,
        Column('id', UUID, primary_key=True),
        Column('project_id', UUID, ForeignKey('projects.id')),
        Column('name', String(255)),
        Column('created_at', TIMESTAMP),
        Column('finished_at', TIMESTAMP),
        Column('items', ARRAY(JSONB)) 
 )

projects = Table('projects', metadata,
        Column("id", UUID, primary_key=True),
        Column("name", String(255))
 )

如果我itemsfeature_obj.

from schema.projects_table import projects
    from schema.features_table import features
    from sqlalchemy import select, func
    from sqlalchemy_utils import json_sql, jsonb_sql,

    async def select_from_list(project_ids: List[UUID]):
        feature_obj = json_sql({
            'id': features.c.id,
            'name': features.c.name,
            'project_id': features.c.project_id,
            'created_at': features.c.created_at,
            'finished_at': features.c.finished_at,
            'items': jsonb_sql(features.c.items) # Works if I remove but doesn't include items list of jsonb
        })
    
        sel_st = select([projects.c.id, projects.c.name, func.json_agg(feature_obj).label('features')]) \
            .select_from(projects.join(features, features.c.project_id == projects.c.id))\
            .where(projects.c.id.in_(project_ids)) \
            .group_by(projects.c.id)
      
        rows = await db.fetch_all(sel_st)
        return rows

这会产生此查询,其中items列似乎没有转换为实际列

SELECT projects.id, projects.name, json_agg(json_build_object('id', features.id, 'name', features.name, 'project_id', features.project_id, 'created_at', features.created_at, 'finished_at', features.finished_at, 'items', :json_build_object_1)) AS features 
FROM projects JOIN features ON features.project_id = projects.id 
WHERE projects.id IN (:id_1, :id_2, :id_3, :id_4) 
GROUP BY projects.id

我得到这个回溯说它无法确定应该是的列类型jsonb[]

   statement = await self._protocol.prepare(stmt_name, query, timeout)
      File "asyncpg/protocol/protocol.pyx", line 163, in prepare
    asyncpg.exceptions.IndeterminateDatatypeError: could not determine data type of parameter $2

任何帮助或指示将不胜感激,因为我已经坚持了几天了。

标签: pythonpostgresqlsqlalchemysqlalchemy-utils

解决方案


推荐阅读