我在我的项目中使用sql alchemy,我使用了db session,
engine = create_engine(configuration)
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()
def init_db():
import models
Base.metadata.create_all(bind=engine)
数据库会话用作:
db_session.merge(order) #order(model) in object
db_session.commit()
现在我想将数据插入到两个表的订单和订单行项中,所以我需要交易, 如: 1.在第一个插入中,我想在第二个插入查询中使用插入的订单ID 2.如果第二次插入查询失败,则第一次查询应该回滚
Try:
#begin transaction/How to begin transaction?
order=db_session.add(order) #insert into order
#is need to commit db_session here as I need inserted orders id
#here actually db_session.commit() needed to get order's id(auto generated)
#if db_session committed here then sql alchemy starts new session
order_line_item.id = order.id
db_session.add(order_line_item) #insert into order line line item
db_session.commit()
#check transaction status if failed then rollback, How to check status?
except:
db_session.rollback()
如何使用trasaction?
答案 0 :(得分:17)
Lafada建议的嵌套交易不适用于此类情况。 flush()
会很好,例如。
db_session.begin()
try:
db_session.add(order)
db_session.flush()
order_line_item.id = order.id
db_session.add(order_line_item)
db_session.commit()
except:
db_session.rollback()
或者更好的是,如果您在订单和订单项之间正确设置了关系,则您甚至不必费心手动分配ID。
答案 1 :(得分:5)
您应该使用SQLAlchemy的relationship
功能,所以不要这样做
不得不乱用外键。例如,您的订单商品可以
看起来像(我假设你有很多关系):
class OrderLineItem(Base):
id = Column(Integer, primary_key=True)
order_id = Column(Integer, ForeignKey('orders.id'))
order = relationship('Order', backref='order_line_items')
在插入时,您只需分配订单实例:
order_line_item.order = order
session.add(order) # you even don't have to insert the item!
在教程中查看更多详细信息:http://docs.sqlalchemy.org/en/latest/orm/relationships.html
答案 2 :(得分:1)
您必须像
一样使用nested transactiontop_trans = connection.begin()
try:
#begin transaction/How to begin transaction?
order_trans = connection.begin()
order=db_session.add(order) #insert into order
order_trans.commit()
order_line_item.id = order.id
order_line_trans = connection.begin()
db_session.add(order_line_item) #insert into order line line item
order_line_trans.commit()
#check transaction status if failed then rollback, How to check status?
except:
top_trans.rollback()
您还可以使用two phase交易。两者都有一个优势,哪一个适合你,你可以使用