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

Playhouse(Peewee扩展)Signals异常:post_save的created参数恒为False

问题原因分析

你的问题出在User模型的UUID主键生成时机和Peewee信号中created参数的判定逻辑上:

  • User模型的id字段设置了default=uuid4,导致实例化User()时就自动生成了主键值
  • Peewee的post_save信号中,created参数的判定依据是实例是否有未保存的主键——因为你的User实例在保存前已经有了主键,即使执行的是INSERT操作,信号仍会认为这是更新操作,所以created始终为False
解决方案

提供三种可行方案,按需选择:

方案1:调整主键生成时机(推荐)

修改User模型的主键定义,让数据库在插入时自动生成UUID(以PostgreSQL为例,其他数据库可适配对应语法),这样实例化时主键为None,保存后Peewee会正确识别为新创建的记录:

import uuid
from peewee import UUIDField, SQL

class User(BaseModel):
    id = UUIDField(primary_key=True, default=None, constraints=[SQL('DEFAULT uuid_generate_v4()')])
    tg_id = BigIntegerField(unique=True, null=True)

注意:PostgreSQL需要先启用uuid-ossp扩展(执行CREATE EXTENSION IF NOT EXISTS "uuid-ossp";)。如果是SQLite,可改用AutoField作为主键,或者在保存前手动生成UUID并赋值。

方案2:绕过信号的created参数判断

直接在信号中检查是否存在对应的UserSettings记录,不存在则创建,彻底摆脱对created参数的依赖:

@post_save(sender=User)
def on_user_created(model_class: User, instance: User, created: bool):
    print("works1")
    # 直接获取或创建UserSettings,自动处理缺失情况
    UserSettings.get_or_create(user=instance)

这种方法更健壮,即使后续业务逻辑变更导致保存方式改变,也能保证UserSettings始终存在。

方案3:在用户创建逻辑中手动关联

如果不想依赖信号,可以在create_or_update_user_tg函数中,当确认是创建新用户时直接生成UserSettings:

def create_or_update_user_tg(tg_id: int, name: str, age: int, city: str,
                             gender: Gender, search_gender: SearchGender,
                             profile_description: str = None, location: Location = None,
                             medias: typing.List[tuple[str]] = None) -> \
        typing.Union[User, None]:

    u, is_creating = User.get_or_none(tg_id=tg_id), False

    if not u:
        u, is_creating = User(), True

    u.tg_id = tg_id
    u.name = name
    u.age = age
    u.city = city
    u.gender = gender.value
    u.search_gender = search_gender.value
    u.profile_description = profile_description

    if location:
        u.longitude = location.longitude
        u.latitude = location.latitude

    u.save(force_insert=is_creating)

    # 新增:创建UserSettings(仅当新用户时)
    if is_creating:
        UserSettings.create(user=u)

    upload_user_medias(u.tg_id, medias, delete_existing=True)
    return u

内容的提问来源于stack exchange,提问作者Bekhruz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 14:03:22