使用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中做到这一点。
答案 0 :(得分:1)
假设您使用的是mysql.connector,autocommit
属性的默认值为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")
但是我没有测试它。根据文件,它应该有效。