13

私は自分のプロジェクトでsqlalchemyを使用しています、dbセッションを使用しました、

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セッション:

db_session.merge(order)      #order(model) in object
db_session.commit()

次に、2つのテーブルorderとorder line itemにデータを挿入したいので、次のようにトランザクションが必要です。1.最初の挿入で、挿入された注文のIDを2番目の挿入クエリで使用します。2。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

SQLAlchemyの機能を使用する必要があるため、relationship外部キーをいじくり回す必要はありません。たとえば、注文アイテムは次のようになります(多対1の関係があると思います)。

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

2フェーズトランザクションを使用することもできます。どちらにも、どちらがあなたに適しているかという利点があります。

于 2012-04-09T04:02:11.257 に答える