SQLAlchemy用Association Object追加关系报NotNullViolation是文档问题吗
问题原因
你遇到的错误是硬套官方示例未替换自定义类/表名导致的,和官方文档无关,具体错误点如下:
- relationship绑定的关联类名错误
你自己定义的关联类叫TopicSubcription,但Topic.subscribed_users和User.followed_topics的relationship里仍然写的是官方示例的类名Association,导致ORM无法正确关联赋值。你把sub追加到u.followed_topics时,ORM不会自动给sub.user赋值,也就不会生成user_id字段值,触发非空约束报错。
- relationship绑定的关联类名错误
- 模型表名配置错误
官方示例里Parent对应表名left、Child对应表名right是示例配置,你自己的代码里关联表外键指向的是topic.id和user.id,但Topic类的__tablename__写的是left,User类的__tablename__写的是right,和外键指向的表名完全不匹配。
- 模型表名配置错误
- 关联类实例化参数错误
你写的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
相关产品推荐
相关产品推荐

