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

Mic*_*ael 8 python mysql session locking sqlalchemy

使用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中这样做.

Dek*_*kel 2

假设您正在使用mysql.connector,该autocommit属性的默认值为 False,这可能会导致您的脚本由于其他会话正在等待完成而挂起。

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

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

Session = sessionmaker(bind=engine, autocommit=True)
Run Code Online (Sandbox Code Playgroud)

另一种选择 - 创建会话后您可以执行SET AUTOCOMMIT=1

s = Session()
s.execute("SET AUTOCOMMIT=0")
Run Code Online (Sandbox Code Playgroud)

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

engine = create_engine("mysql+mysqlconnector://user:pass@localhost/dbname?autocommit=1")
Run Code Online (Sandbox Code Playgroud)

不过我没有测试过。根据文档它应该有效。

  • [sqla 文档](http://docs.sqlalchemy.org/en/latest/orm/session_transaction.html#autocommit-mode) 首先提到的事情之一是:“**警告**“自动提交”模式应该**不考虑用于一般用途**。” (2认同)