SQLAlchemy I/O 其中参数

SQLAlchemy I/O where parameters

我目前正在处理一个项目,该项目的数据库是通过 SQLAlchemy I/O 使用的,我偶然发现了一个我无法解决的问题。下面的DbSession是异步会话,select是库的select函数

我有一个class播放器,有3个属性id:BigInteger(主键),name:String,other_id(可为空,如果不为null可以作为主键):BigInteger。

class Player(Base):
    __tablename__ = "players"
    id = Column(Integer, primary_key=True)
    name = Column(String)
    other_id = Column(BigInteger, nullable=True)

我实现了 2 个方法 get 和 get_by_id: get 运行良好,select table 中的玩家通过其 id:

    @classmethod
    async def get(cls, id):
        query = select(cls).where(cls.id == id)
        results = await DbSession.execute(query)
        result = results.scalars().all()[0]
        return result

我的问题来自 get_by_id,它应该通过 other_id.

找到玩家

我试过了:


    @classmethod
    async def get_dc_id(cls, id):
        query = select(cls).filter(cls.other_id == id)
        results = await DbSession.execute(query)
        result = results.scalars().all()[0]
        return result

以及:


    @classmethod
    async def get_dc_id(cls, id):
        query = select(cls).where(cls.other_id == id)
        results = await DbSession.execute(query)
        result = results.scalars().all()[0]
        return result

但都发回一个错误:


ProgrammingError: (sqlalchemy.dialects.postgresql.asyncpg.ProgrammingError) <class 'asyncpg.exceptions.UndefinedFunctionError'>: operator does not exist: character varying = bigint
HINT:  No operator matches the given name and argument types. You might need to add explicit type casts.
[SQL: SELECT players.id, players.name, players.other_id 
FROM players 
WHERE players.other_id = %s]
[parameters: (331534096054616068,)]

如果我没理解错的话,调用的参数实际上是我给函数的 id,但包装在一种元组中(我不知道从哪里来的)。它抛出一个错误,因为这个元组与 BigInteger other_id 应该具有的类型不匹配。我多次检查我有效地给出了一个整数作为 get_by_id 的参数(这里等于 331534096054616068)。我必须承认,我不知道为什么 id 最终被包裹在一个元组中,这是否是正常行为,因为我刚开始使用 sqlalchemy。

任何提示或帮助将不胜感激。

您的实际架构似乎有所不同,other_id 是一个 STRING 列。

你能用 psql 直接检查 postgresql 数据库并检查 \d players 是否正确吗?

如果我将您的列定义更改为 other_id = Column(String, nullable=True) 并创建数据库架构,我会遇到同样的错误,但如果我使用 other_id = Column(BigInteger, nullable=True).

重新创建架构,它会起作用