12

コードはsqlahcmeyのormチュートリアルからのステップバイステップのコピーですが、最後の行を除いて、クエリの後にすべてのテーブルを削除するつもりでした。ただし、ブロックされたプログラムBase.metadata.drop_all(bind=engine)は、その時点でのMySQLのステータスです(MySQL Workbenchから取得)。

ワークベンチ管理者

マークされた行が示すように、ドロップテーブルプロセスがのためにハングしました 。その行が削除された場合にプログラムがブロックされなかったためtable metadata lockにメタデータロックが発生したことをお勧めしますが、理由はまだわかりません。result = session.query(User).all()だから私の質問は:なぜこれが起こったのか、ブロッキングを回避する方法

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String


Base = declarative_base()


class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(16))
    fullname = Column(String(16))
    password = Column(String(16))

    def __init__(self, name, fullname, password):
        self.name = name
        self.fullname = fullname
        self.password = password

    def __repr__(self):
        return "<User('%s','%s', '%s')>" % (self.name, self.fullname, self.password)


uri = 'mysql://root:zxsaqw21@localhost/test_sa'
engine = create_engine(uri, echo=False)

Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)
session = Session()

user = User('ed', 'Ed Jones', 'edspassword')
session.add(user)
session.commit()

result = session.query(User).all()
print len(result)

Base.metadata.drop_all(bind=engine)
4

1 に答える 1

20

drop_all() を実行する前に、session.close() (または commit()、または rollback()) を呼び出します。セッションはまだ開いているトランザクション上にあります。

チュートリアルは、積極的なテーブル ロックを持たない sqlite に対するものです (ここでは、MySQL DB が InnoDB を使用していると想定しています)。

于 2012-12-14T16:21:58.303 に答える