在Sqlalchemy查询中忽略MYSQL数据库中的锁定

时间:2016-07-14 18:49:42

标签: python mysql session sqlalchemy locking

使用SQLAlchemy查询MySQL数据库我收到以下错误:

  

sqlalchemy.exc.OperationalError: (raised as a result of Query-invoked autoflush; consider using a session.no_autoflush block if this flush is occurring prematurely) (_mysql_exceptions.OperationalError) (1205, 'Lock wait timeout exceeded; try restarting transaction')

首先,我假设错误消息注释到"如果过早地发生此刷新,则考虑使用session.no_autoflush块"是关于放置锁的另一个会话,而不是我用于当前查询的会话?如果我遵循这个建议,这有助于避免一般的数据库锁定?其次,我只需要阅读并且不需要对查询结果进行修改,所以我想知道如何忽略锁并只读取当前数据库中的内容。我相信sql是NOWAIT,但我不知道如何在sqlalchemy API中做到这一点。

1 个答案:

答案 0 :(得分:1)

假设您使用的是mysql.connectorautocommit属性的默认值为False,这可能会导致您的脚本因等待完成的其他会话而挂起。

SQLAlchemy正在使用BEGIN statements(别名START TRANSACTION)导致会话获取表/数据库的LOCK,并且您的连接将等到锁定获得批准

要克服此行为(并且由于您说您只需要在会话期间读取数据),您可以在创建会话时设置autocommit = True:

Session = sessionmaker(bind=engine, autocommit=True)

另一个选项 - 创建会话后,您可以执行SET AUTOCOMMIT=1

s = Session()
s.execute("SET AUTOCOMMIT=0")
  

您还可以尝试直接在连接字符串中设置autocommit属性:

engine = create_engine("mysql+mysqlconnector://user:pass@localhost/dbname?autocommit=1")
  

但是我没有测试它。根据文件,它应该有效。