SqlAlchemy:请求导致语法错误,尽管请求不是手动创建的

问题描述 投票:0回答:1

我正在将一些使用 SQLite 的基于 SQLAlchemy2 的代码迁移到 PostgreSQL(SQLAlchemy 2.0.8、psycopg2-binary 2.9.1、Python 3.10、PostgreSQL 15 服务器)。结果令人惊讶:非手动创建的请求中存在语法错误(我很容易想象手动创建的请求中存在错误,但很难想象通过 API 创建的请求而不直接使用 SQL 语言会出现类似的问题)。我将示例改进为一个简约的程序。在这里。

from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
from sqlalchemy import create_engine, select


class Base(DeclarativeBase):
    ...


class Obj(Base):
    __tablename__ = "objects"
    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str] = mapped_column(index=True, nullable=False)


def read(dburl: str) -> None:
    engine = create_engine(dburl, echo=True)
    Base.metadata.create_all(engine)
    session = Session(engine)
    stmt = select(Obj).where(Obj.name.is_('some_name'))
    if session.scalars(stmt).first():
        print("Found")


read('sqlite://')
#read('postgresql://user:passwd@HOST:5432/dbname')

当我以初始形式执行程序时,它成功了。当我注释掉 SQLite URL 并取消注释 Postgres URL 时,它会以下列方式失败:

psycopg2.errors.SyntaxError: ERROR:  syntax error at or near 'some_name'
LINE 3: WHERE objects.name IS 'some_name'

带参数的请求,根据日志,是:

[SQL: SELECT objects.id, objects.name 
FROM objects 
WHERE objects.name IS %(name_1)s]
[parameters: {'name_1': 'some_name'}]

对我来说,这个要求似乎很理智。表已成功创建,其结构完全符合预期,但第一个

SELECT
失败。可能是什么原因以及如何解决?

UPD:
已找到修复程序(请参阅我的答案)。但原因还没有,所以我还不会接受我自己的答案。

python postgresql sqlalchemy psycopg2
1个回答
0
投票

stmt = select(Obj).where(Obj.name.is_('some_name'))
更改为
stmt = select(Obj).where(Obj.name == 'some_name')
即可解决问题。虽然我还是不明白原因。

© www.soinside.com 2019 - 2024. All rights reserved.