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

SQLAlchemy用Association Object追加关系报NotNullViolation是文档问题吗

问题原因

你遇到的错误是硬套官方示例未替换自定义类/表名导致的,和官方文档无关,具体错误点如下:

    1. relationship绑定的关联类名错误
      你自己定义的关联类叫TopicSubcription,但Topic.subscribed_users和User.followed_topics的relationship里仍然写的是官方示例的类名Association,导致ORM无法正确关联赋值。你把sub追加到u.followed_topics时,ORM不会自动给sub.user赋值,也就不会生成user_id字段值,触发非空约束报错。
    1. 模型表名配置错误
      官方示例里Parent对应表名left、Child对应表名right是示例配置,你自己的代码里关联表外键指向的是topic.id和user.id,但Topic类的__tablename__写的是left,User类的__tablename__写的是right,和外键指向的表名完全不匹配。
    1. 关联类实例化参数错误
      你写的sub = TopicSubscription(func.now())没有指定参数名,ORM不会自动把这个值对应到subscription_date字段,需要显式指定参数名。
修正后的代码

模型定义部分

class TopicSubcription(Base):
    __tablename__ = 'topic_subscription'
    topic_id = Column(ForeignKey('topic.id'), primary_key=True)
    user_id = Column(ForeignKey('user.id'), primary_key=True)
    subscription_date = Column(DateTime, nullable=True)
    topic = relationship("Topic", back_populates="subscribed_users")
    user = relationship("User", back_populates="followed_topics")

class Topic(Base):
    __tablename__ = 'topic' # 替换为实际表名
    id = Column(Integer, primary_key=True)
    subscribed_users = relationship("TopicSubcription", back_populates="topic") # 替换为自己的关联类名

class User(Base):
    __tablename__ = 'user' # 替换为实际表名
    id = Column(Integer, primary_key=True)
    followed_topics = relationship("TopicSubcription", back_populates="user") # 替换为自己的关联类名

业务代码部分

u: User = session.query(User).filter(User.id == 'example_id1').one()
t: Topic = session.query(Topic).filter(Topic.id == 'example_id2').one()
sub = TopicSubscription(subscription_date=func.now()) # 显式指定字段名
sub.topic = t
u.followed_topics.append(sub)
session.add(u)
session.commit()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 14:15:02