【发布时间】:2018-01-08 19:29:28
【问题描述】:
我正在使用 sqlalchemy 范围会话,无法正确更新现有行。
这是我的模型:
db = scoped_session(sessionmaker())
Base = declarative_base()
class Song(Base):
__tablename__ = 'song'
id = Column(Integer, primary_key=True)
artist_id = Column(Integer, ForeignKey('artist.id'))
artist_title = Column(Text)
title = Column(Text)
artist = relationship('Artist', backref='songs')
preview_url = Column(Text, default=None)
class Artist(Base):
__tablename__ = 'artist'
id = Column(Integer, primary_key=True)
title = Column(Text)
similar_artists = relationship('Artist',
secondary=followers,
primaryjoin=(followers.c.follower_id == id),
secondaryjoin=(followers.c.followed_id == id),
backref=backref('followers', lazy='dynamic'),
lazy='dynamic')
Index('my_index', Artist.id, unique=True, mysql_length=255)
我已经填充了数据库,可以看到 Song 行的所有列都在调试器和 pgweb 界面中填充了数据。在视图中,我进行查询以获取歌曲列表并希望按如下方式更新它们:
# song.artist_id has an integer value
song.preview_url = preview_url # Just a string
# db.query(Song).filter(Song.id == song.id).update({'preview_url':preview_url}) #Produces same result as above
db.commit()
# song.artist_id becomes None
这会将 preview_url 添加到一行,但是,一旦我这样做并提交,即使我更新了完全不同的字段,艺术家.id 在歌曲实例中也会变为 None。我可以在调试器和 pgweb 界面中观察到这一点。
更新:我在对行进行任何更改之前尝试了db.commit(),它仍然用None 替换song.artist_id。这意味着行更新与此无关,因此它必须是我在song 上所做的预处理。有什么方法可以在更新和提交行之前摆脱会话中的所有更改?
有没有人遇到过这种行为?我是否必须再次显式设置 artist.id,因为它是外键?
【问题讨论】:
-
不,您不需要再次指定artist.id。数据是否成功更新/提交到数据库中?
-
请提供minimal reproducible example。你提到了一些“预处理”。也包括在内。
标签: python sqlalchemy pyramid