使用Peewee ORM查询报错:列t2.is_successful_authorized不存在
Peewee动态模型继承导致表别名错误的成因分析
核心原因
每次访问database.metamask这个@property时,都会动态创建一个全新的Metamask模型类。Peewee会将每个独立的模型类视为不同的数据库表,因此会分配不同的表别名,这就是问题的根源。
具体执行过程拆解
- 执行
database.metamask.select()时,第一次调用metamask属性,生成第一个Metamask模型,Peewee为其分配表别名t1,对应SQL中的查询表t1。 - 在
where()条件中再次访问database.metamask.is_successful_authorized时,第二次调用metamask属性,生成了另一个完全独立的Metamask模型类,Peewee为这个新模型分配了表别名t2。 - 最终生成的SQL里,查询主体用的是
t1表,但WHERE条件却引用了t2表的字段,数据库找不到t2.is_successful_authorized这个列,自然抛出错误。
佐证依据
从你提供的SQL语句可以明确看到矛盾点:
SELECT "t1"."id", "t1"."password", "t1"."is_successful_authorized", "t1"."mnemonic" FROM "metamask" AS "t1" WHERE ("t2"."is_successful_authorized" IS NULL)
- SELECT子句全部引用
t1表的字段 - WHERE条件却引用了
t2表的字段,完全是因为两次metamask属性调用生成了两个独立模型。
解决方案思路
不要每次访问都动态创建新模型,而是将Metamask模型缓存起来,比如在类初始化时创建一次并保存为实例属性,而非用@property动态生成:
class YourDatabaseClass: def __init__(self, db): self.__sql_db = db # 初始化时创建一次模型并缓存 self._metamask_model = self._create_metamask_model() def _create_metamask_model(self): class AccountModel(Model): password = CharField(max_length=255) is_successful_authorized = BooleanField(null=True, default=None) class Meta: database = self.__sql_db class Metamask(AccountModel): mnemonic = CharField(max_length=255) return Metamask @property def metamask(self): return self._metamask_model
内容的提问来源于stack exchange,提问作者blnk.off
相关产品推荐
相关产品推荐

