You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Peewee ORM查询报错:列t2.is_successful_authorized不存在

Peewee动态模型继承导致表别名错误的成因分析

核心原因

每次访问database.metamask这个@property时,都会动态创建一个全新的Metamask模型类。Peewee会将每个独立的模型类视为不同的数据库表,因此会分配不同的表别名,这就是问题的根源。

具体执行过程拆解

  1. 执行database.metamask.select()时,第一次调用metamask属性,生成第一个Metamask模型,Peewee为其分配表别名t1,对应SQL中的查询表t1。
  2. 在where()条件中再次访问database.metamask.is_successful_authorized时,第二次调用metamask属性,生成了另一个完全独立的Metamask模型类,Peewee为这个新模型分配了表别名t2。
  3. 最终生成的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 03:33:24