The code is a step-by-step copy from sqlahcmey's orm tutorial, except the last line,
I intended to drop all tables after the query. But the program blocked on Base.metadata.drop_all(bind=engine)
, below is the status of MySQL at that time(taken from MySQL Workbench):
As the marked line shows, the drop table process was hanged due to the
table metadata lock
, I suggest the metadata lock was caused by result = session.query(User).all()
since the program did not block if that line was removed,
but I still don't know the reason. So my question is: Why did this happen, how to avoid the blocking
#!/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)
Just call drop() against the table object. From the docs: Issue a DROP statement for this Table, using the given Connectable for connectivity. This only works if the table exists, it will give an error if you delete the whole .
You delete everything in the database using the db. drop_all() function to add the tags and post_tag tables safely and to avoid any of the common issues related to adding new tables to a database. Then you create all the tables anew using the db. create_all() function.
The SQL Expression Language constructs its expressions against table columns. SQLAlchemy Column object represents a column in a database table which is in turn represented by a Tableobject. Metadata contains definitions of tables and associated objects such as index, view, triggers, etc.
call session.close() (or commit(), or rollback()) before you do the drop_all(). the session is still sitting on an open transaction.
the tutorial is against sqlite which doesn't have aggressive table locking (I'm assuming your MySQL DB is using InnoDB here).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With