gpt4 book ai didi

python - 如何在 Flasksqlachemy 中同时插入父表和子表?

转载 作者:行者123 更新时间:2023-12-03 08:47:27 24 4
gpt4 key购买 nike

我正在使用 FlaskSqlachemy 和 Postgresql 数据库。

我有一个名为“Order”的表和一个名为“Attempt”(尝试交付订单)的表,它们处于一对多关系。尝试表有一个 order.id 的 FK。

我想在同一 session 中将记录插入到 Order 和 Attempt 表中。问题是我在插入之前不知道 order.id 。因为order.id是具有自增功能的Order表的PK。

我可以先插入订单,然后检查 order.id,最后插入尝试。我的问题是:如果第二次插入失败,我最终会得到一个没有与之关联的尝试的订单。

这种情况下的最佳实践是什么?

下面是我的数据库模型的简化版本:

class Order(db.Model):
id = db.Column(db.Integer, primary_key=True)
attempts = db.relationship('Attempt', backref='order', lazy='select',
order_by="Attempt.date")

class Attempt(db.Model):
id = db.Column(db.Integer, primary_key=True)
order_id = db.Column(None, db.ForeignKey('order.id'))

下面是我现在的解决方案:

    # Create an order object
new_order = Order()

# Try to add it to db
try:
db.session.add(new_order)
db.session.commit()
except Exception:
....
return redirect(url_for('scheduleorder'))
else:
order = Order.query.filter_by(token=token).first()

# Create an attempt object
new_attempt = Attempt(order_id=order.id)
try:
db.session.add(new_attempt)
db.session.commit()
except Exception:
...
return redirect(url_for('scheduleorder'))
else:
...
return redirect(url_for('scheduleorder'))

最佳答案

我建议使用flush(),而不是使用commit()来保存对数据库的更改。 Flush 将更改推送到数据库事务缓冲区,即您的对象被创建并放置在缓冲区内,但并未真正作为记录写入您的数据库。之所以如此,是因为如果在该 session 中发生异常(就像您的情况一样,如果插入命令失败),我们将使用 rollback() 方法回滚到之前的状态。


这非常适合您的用例,因为当您创建对象并使用刷新方法时,您可以访问在数据库中自动递增的 id,在您的代码中进一步使用。遇到异常时不要忘记使用 db.session.rollback() 来实际回滚事务。

# Create an order object
new_order = Order()

# Try to add it to db
try:
db.session.add(new_order)
db.session.flush()
order_id = new_order.id

except Exception:
....
db.session.rollback()
return redirect(url_for('scheduleorder'))
else:

# Create an attempt object
new_attempt = Attempt(order_id=order_id)
try:
db.session.add(new_attempt)
db.session.flush()
except Exception:
...
db.session.rollback()
return redirect(url_for('scheduleorder'))
else:
...
return redirect(url_for('scheduleorder'))

# use the commit at the end of you usecase so that you actually create a record in your database.
db.session.commit()

关于python - 如何在 Flasksqlachemy 中同时插入父表和子表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60835382/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com