13

我在我的项目中使用 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()

如何使用交易?

4

3 回答 3

18

Lafada 建议的嵌套交易不适用于这种情况。Aflush()会做得很好,例如

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。

于 2012-04-09T07:06:15.333 回答
6

你应该使用relationshipSQLAlchemy 的特性,所以你不必乱用外键。因此,例如,您的订单项目可能看起来像(我假设您有一个多对一的关系):

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

于 2013-01-14T14:47:50.533 回答
2

你必须像用户嵌套事务一样

top_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()

您也可以使用两阶段事务。两者各有优势,哪一款适合你,你可以使用

于 2012-04-09T04:02:11.257 回答