SQLAlchemy执行SQL时自动转小写表名报错,如何禁用该特性?
SQLAlchemy执行SQL时表名自动转小写导致找不到表的解决办法
问题场景
使用sqlalchemy==1.4.31执行以下原生SQL查询:
with get_postgres_db() as postgres_session: r = postgres_session.execute("SELECT * FROM shop.Clients;")
执行后触发报错:
ProgrammingError: (psycopg2.errors.UndefinedTable) relation "shop.clients" does not exist
但通过查询information_schema可确认shop.Clients表确实存在:
In [30]: with get_postgres_db() as postgres_session: ...: r = postgres_session.execute("SELECT * FROM information_schema.tables WHERE table_schema = 'shop';") ...: In [31]: r.all() Out[31]: [('DB', 'shop', 'Clients', 'BASE TABLE', None, None, None, None, None, 'YES', 'NO', None), ...]
问题表现为SQL语句中的表名被自动转换为小写,导致无法匹配实际存在的大小写敏感表,用户原本是在创建清空表的装饰器时遇到该问题。
解决办法
1. 原生SQL查询时手动添加双引号
PostgreSQL的标识符规则是:未用双引号包裹的标识符会被自动转为小写存储/匹配;若创建表时用双引号保留了大小写(如CREATE TABLE "shop"."Clients"),则查询时必须用双引号包裹标识符才能匹配。
修改SQL语句,给表名和模式名加上双引号:
# 查询表 with get_postgres_db() as postgres_session: r = postgres_session.execute('SELECT * FROM "shop"."Clients";') # 清空表 with get_postgres_db() as postgres_session: postgres_session.execute('DELETE FROM "Clients";')
2. ORM模型中配置标识符大小写保留
如果使用SQLAlchemy ORM定义模型,可通过以下方式确保表名大小写被保留:
- 全局元数据配置启用标识符引用:
from sqlalchemy import MetaData from sqlalchemy.ext.declarative import declarative_base # 全局设置所有表名、字段名自动添加双引号 metadata = MetaData(quote=True) Base = declarative_base(metadata=metadata) - 单独为模型配置表名:
这样ORM生成的SQL会自动给标识符添加双引号,避免大小写被转换。class Clients(Base): __tablename__ = "Clients" __table_args__ = {"schema": "shop", "quote": True} # 字段定义示例 id = Column(Integer, primary_key=True)
内容的提问来源于stack exchange,提问作者El Dude
相关产品推荐
相关产品推荐

