0

我正在开发一个小项目来学习 SQLAlchemy,我正在使用 Flask 和 Flask-SQLAlchemy。该项目旨在模拟一堆电视节目及其剧集。

当涉及到 SQLAlchemy 中的 INSERT OR UPDATE(或“upserts”)时,我正试图围绕最佳实践进行思考,但我无法克服这个障碍。似乎每当我创建模型实例时,SQLAlchemy(或 Flask-SQLAlchemy)都会INSERT发表声明!这很奇怪,我认为这是不对的,但也许我错过了什么?

这里是模型的简化版本Episode,它使用由三列值组成的复合主键,其中一个是模型的外键Show

class Episode(db.Model):
    title = db.Column(db.String(256))
    season = db.Column(db.Integer, primary_key=True)
    episode = db.Column(db.Integer, primary_key=True)

    # relationships
    show_id = db.Column(db.Integer, db.ForeignKey('show.id'), primary_key=True)
    show = db.relationship('Show', backref=db.backref('episodes', lazy='dynamic'))

这是似乎生成INSERT语句的代码:

show = Show.query.filter_by(something=139).first()
ep = Episode(**{'title': 'foo',
                'show': show,
                'season': 39,
                'episode': 1})
db.session.commit()

我猜这与我引用一个持久对象有关,但这肯定不应该生成一个INSERT?

任何帮助表示赞赏!

我在 Windows 系统上使用 Python 2.7。我正在使用 Flask 0.10.1、Flask-SQLAlchemy 1.0 和 SQLAlchemy 0.8.3,它们都是通过 pip 安装的。

4

1 回答 1

1

您面临的问题与所谓的级联有关。简而言之,它的工作原理如下:如果您正在使用的对象之一已经在会话中(在这种情况下Show,因为您通过会话从数据库中查询它),那么它也会将其级联到其他对象与此有关。

如果您不希望这样,有一种方法可以禁用此行为:

    show = db.relationship('Show', backref=db.backref('episodes', lazy='dynamic'), cascade=None)

我不是 100% 确定这None是正确的值,因为我在文档中找不到这个,我只发现它False表示“使用默认值”。

作为旁注,我想知道您为什么要这样做。从我在问题描述中读到的内容,我宁愿这样做:

ep = Episode.query.filter(Episode.show_id == 139).filter(Episode.season == 39).filter(Episode.episode == 1).first()
if ep:
    # update
else:
    # create new
于 2013-10-28T22:20:25.003 回答