2016-07-14 20 views
8

MYSQL veritabanında Kilidi Ignore:aşağıdaki hatayı alıyorum MySQL veritabanını sorgulamak için SQLAlchemy kullanma sqlalchemy Query

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')

Birincisi, hata mesajı comment "Bir session.no_autoflush bloğunu kullanmayı düşünün varsayalım eğer bu floş vaktinde meydana geliyorsa, mevcut sorgum için kullanacağım seansı değil, kilidin yerleştirildiği diğer oturum hakkında mı? Bu tavsiyeyi izlediysem, bu genel olarak veritabanındaki kilitleri önlemeye yardımcı olur mu? İkincisi, sadece okumaya ve sorgu sonuçlarına değişiklik yazmam gerekmiyor, bu yüzden kilidin nasıl göz ardı edileceğini ve sadece veritabanında ne olduğunu okumayı öğrenmek istiyorum. SQL'in NOWAIT olduğuna inanıyorum, ancak bunu sqlalchemy API'sinde nasıl yapacağımı göremiyorum.

+0

Lütfen SQL deyimlerini (her iki bağlantıda) ve 'CREATE TABLE' komutunu ve 'ENGLISH = InnoDB STATUS' (lütfen sorun oluştuğunda) verin. Sağladığınızdan, neden kilitlendiğini ve bir çok önemli ayrıntıyı anlatamayız. –

+0

Ayrıca sqlalchemy'nin "no_autoflush" hakkında bilgi sağlayın; MySQL yapısının kapakların altında olduğunu anlamaya ihtiyacımız var. –

+0

@RickJames hiçbir SQL [autoflush] alt yapısı oluşturmaz (http://docs.sqlalchemy.org/en/latest/orm/session_api.html#sqlalchemy.orm.session.Session.params.autoflush). SQLAlchemy oturumunun durumu nasıl ele aldığıdır. Oturumda beklemede olan değişiklikler DB'ye henüz eklenmemişse (ekler, güncelleştirmeler, silmeler), autoflush kullanımdaysa, sonraki sorgulamadan önce bunları DB'ye aktarabilir. Bir mcve olmadan OP yardımcı olamaz, bir şey kilitli bir şey kilitleme ve bir sorgu kilitli bir şey kullanmadan önce verilir ... –

cevap

1

mysql.connector'u kullandığınız varsayılırsa, autocommit Mülkünün varsayılan değeri False'dir, bu da komut dosyanızın bitirmeyi bekleyen diğer oturum nedeniyle askıda kalmasına neden olabilir.

SQLAlchemy tablo/veritabanı KİLİT elde etmek oturumu neden BEGIN statements, (START TRANSACTION ait takma ad) kullanıyor ve kilit onaylanacak kadar bağlantı bekleyecektir.

bu davranışı aşmak (ve bağlı Eğer sadece oturumu sırasında veri OKUYUN gerektiğini söyledi gerçeğine) Eğer özdevinimli ayarlayabilirsiniz için = Doğru senin Oturumu oluştururken:

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

Başka bir seçenek - senden sonra

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

You can also try to set the autocommit property directly in the connection string:

engine = create_engine("mysql+mysqlconnector://user:[email protected]/dbname?autocommit=1") 

However I didn't test it. According to the documentations it should work.

: Eğer SET AUTOCOMMIT=1 yürütebileceği oturumu oluşturmak
+0

Will Herhangi bir Aşağı oy için bir açıklama için teşekkür ederiz – Dekel

+1

[sqla belgelerinde] belirtilen ilk şeylerden biri (http: // docs.sqlalchemy.org/en/latest/orm/session_transaction.html#autocommit-mode): "** Uyarı **" autocommit "modu ** genel kullanım için dikkate alınmamalıdır **." –

+0

@ IljaEverilä, autocommit = Doğru gerçekten iyi bir uygulama değil, bu yüzden bu şekilde bir işlem kodu (örneğin salt okunur komut dosyası) gerektirmiyorsa, belgede bu şekilde bahsedilir. autocommit = True ile bu işleme sahip sunucu için daha ucuz. SQLAlchemy'nin autocommit = her seans için yanlış olması gerçeği her zaman iyi bir uygulama değildir. Üstelik - MyISAM motorunu kullanıyorsanız, işlem yapmak mantıklı değildir ve orada autocommit = True olması daha da iyidir. – Dekel