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

Peewee ORM一对一关联创建实例报错TypeError:无法转换Email对象为int

Peewee一对一关联创建实例报错原因分析

问题描述

使用Peewee作为ORM定义了具有一对一关联的模型,创建Email实例成功,但创建Linkedin实例时触发类型错误:TypeError: int() argument must be a string, a bytes-like object or a real number, not 'Email'。

模型代码

def __account_model(self) -> Type[Model]:
    db = self.__sql_db

    class AccountModel(Model):
        password = CharField(max_length=255)
        is_successful_authorized = BooleanField(null=True, default=None)

        class Meta:
            database = db

    return AccountModel

def linkedin(self) -> Type[Model]:
    model = self.__account_model

    class Linkedin(model):
        email = ForeignKeyField(self.email, backref='linkedin')
        cookies = TextField(null=True, default=None)

    return Linkedin

def email(self) -> Type[Model]:
    model = self.__account_model

    class Email(model):
        login = CharField(max_length=255)

    return Email

实例创建代码

password, email_login, email_password, cookies = account.values()
email=controller.email.create(password=email_password,login=email_login)
model.create(password=password, email=email, cookies=cookies)

错误栈

Traceback (most recent call last):
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/accounts/build_database.py", line 17, in <module>
    db.build([ModelType.LINKEDIN, ModelType.FACEBOOK, ModelType.GOOGLE,
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/accounts/database.py", line 66, in build
    model.create(password=password, email=email, cookies=cookies)
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 6577, in create
    inst.save(force_insert=True)
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 6787, in save
    pk = self.insert(**field_dict).execute()
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 1966, in inner
    return method(self, database, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 2037, in execute
    return self._execute(database)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 2842, in _execute
    return super(Insert, self)._execute(database)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 2555, in _execute
    cursor = database.execute(self)
             ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 3253, in execute
    sql, params = ctx.sql(query).query()
                  ^^^^^^^^^^^^^^
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 628, in sql
    return obj.__sql__(self)
           ^^^^^^^^^^^^^^^^^
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 2819, in __sql__
    self._simple_insert(ctx)
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 2669, in _simple_insert
    return self._generate_insert((self._insert,), ctx)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 2791, in _generate_insert
    return ctx.sql(CommaNodeList(all_values))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 628, in sql
    return obj.__sql__(self)
           ^^^^^^^^^^^^^^^^^
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 1832, in __sql__
    ctx.sql(self.nodes[n_nodes - 1])
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 628, in sql
    return obj.__sql__(self)
           ^^^^^^^^^^^^^^^^^
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 1830, in __sql__
    ctx.sql(self.nodes[i])
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 628, in sql
    return obj.__sql__(self)
           ^^^^^^^^^^^^^^^^^
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 1430, in __sql__
    return ctx.value(self.value, self.converter)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 640, in value
    value = converter(value)
            ^^^^^^^^^^^^^^^^
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 5417, in db_value
    return self.rel_field.db_value(value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 4744, in db_value
    return value if value is None else self.adapt(value)
                                       ^^^^^^^^^^^^^^^^^
  File "/Users/blnkoff/PycharmProjects/gitcoin-passport-bot/venv/lib/python3.11/site-packages/peewee.py", line 4804, in adapt
    return int(value)
           ^^^^^^^^^^
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'Email'

报错原因

1. 父模型重复创建

__account_model方法每次调用都会生成一个全新的AccountModel类,导致Email和Linkedin继承的是完全独立的父模型类。Peewee无法识别这两个模型之间的关联关系,数据库层面也无法共享主键约束。

2. ForeignKeyField参数错误

在Linkedin模型中,ForeignKeyField(self.email, backref='linkedin')传入的是self.email方法对象,而非实际的Email模型类。Peewee无法正确解析外键关联的目标模型,插入时尝试将整个Email实例转换为整数(主键类型),从而触发类型错误。

修复方案

1. 缓存父模型类

修改__account_model,确保只生成一次父模型类:

def __init__(self):
    self.__cached_account_model = None
    # 其他初始化逻辑...

def __account_model(self) -> Type[Model]:
    if not self.__cached_account_model:
        db = self.__sql_db
        class AccountModel(Model):
            password = CharField(max_length=255)
            is_successful_authorized = BooleanField(null=True, default=None)

            class Meta:
                database = db
        self.__cached_account_model = AccountModel
    return self.__cached_account_model

2. 修正外键字段参数

在Linkedin模型中,正确传入Email模型类(调用self.email()方法获取):

def linkedin(self) -> Type[Model]:
    model = self.__account_model()  # 调用方法获取父模型类
    class Linkedin(model):
        email = ForeignKeyField(self.email(), backref='linkedin')  # 传入实际的Email模型类
        cookies = TextField(null=True, default=None)

    return Linkedin

3. 修正模型继承调用

Email模型的继承也需要调用__account_model()方法,确保继承的是缓存的父模型:

def email(self) -> Type[Model]:
    model = self.__account_model()
    class Email(model):
        login = CharField(max_length=255)

    return Email

内容的提问来源于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 10:44:52