PeeWee为何给表名加引号?集成SQL Relay遇该问题咨询
PeeWee表名带引号的原因及SQL Relay集成解决方案
为什么PeeWee会给表名加引号?
其实这是PeeWee遵循ANSI SQL标准的设计,主要是为了避坑和兼容:
- 当表名/字段名是SQL关键字(比如
user、order)、包含空格或特殊字符时,引号能让数据库把它们当成普通标识符,而不是SQL命令的一部分,避免语法报错。 - 不同数据库对标识符的处理逻辑不同(比如MySQL用反引号,PostgreSQL用双引号),PeeWee默认用双引号作为ANSI标准的分隔符,会根据官方适配的数据库自动调整格式——但像SQL Relay这种自定义适配器如果没做适配,就会直接输出双引号,导致兼容问题。
解决SQL Relay集成时的引号问题
针对你使用SQLRelayDatabase的场景,有两种实用的解决方法:
方法1:自定义SQL Relay数据库类,调整引号规则
直接重写SQLRelayDatabase的标识符引用配置,让它生成SQL Relay能识别的格式:
from peewee import BooleanField, CharField, DateField, ForeignKeyField, Model from SQLRelay import PySQLRDB from sqlrelay_ext import SQLRelayDatabase # 自定义适配SQL Relay的数据库类 class SQLRelayDBFix(SQLRelayDatabase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 关键配置:如果SQL Relay不需要引号就设为空字符串 self.identifier_quote_char = '' # 如果SQL Relay要求用反引号,就改成` # self.identifier_quote_char = '`' # 替换原来的DB实例 DB = SQLRelayDBFix('test2', host='<hostname>', user='<username>', password='<password>') # 你的Model定义保持不变 class BaseModel(Model): class Meta: database = DB class ExampleModel(BaseModel): name = CharField() created_at = DateField() is_valid = BooleanField()
方法2:全局禁用标识符引用(适合表名无特殊字符的场景)
如果你的所有表名、字段名都符合SQL命名规范(没有关键字、空格),可以直接全局修改PeeWee的默认配置,彻底关掉引号:
from peewee import Database # 全局设置标识符引用字符为空,生成的SQL就不会带引号了 Database.identifier_quote_char = ''
这种方法简单直接,但要注意会影响所有PeeWee数据库连接,适合项目里没有特殊命名表的情况。
验证修改是否生效
改完之后可以打印一条SQL语句确认效果:
print(ExampleModel.select().sql())
如果输出的SQL里表名和字段名没有双引号,就说明配置生效了。
内容的提问来源于stack exchange,提问作者Nicholas Tulach
相关产品推荐
相关产品推荐

