Maaf jika ini ditanyakan sebelumnya, tetapi saya mencari di mana-mana dan tidak dapat menemukan solusi untuk masalah saya.

Saya mencoba mencapai tugas yang sangat sederhana, yaitu mengirim kueri ke postgres DB dari beberapa utas secara bersamaan.

Ini adalah pengaturan saya:

engine = create_engine(
    f'postgresql://postgres:{password}@{host}:5432/dbname',
    pool_pre_ping=True).connect().execution_options(
    schema_translate_map={None: "my_db"})
Session = scoped_session(sessionmaker(bind=engine))

@contextmanager
def db_session():
    session = Session()
    try:
        yield session
        session.commit()
    except:
        session.rollback()
        raise
    finally:
        session.close()

Inilah yang saya coba jalankan dari setiap utas (mencoba menggunakan Utas python asli dan juga menggunakan APScheduler:

def query_build():
    with db_session() as session:
        session.query(Build).filter(Build.number == -1).all()

Jika saya menjalankan metode di atas dari 2 utas atau lebih, saya terus-menerus menerima pengecualian di bawah ini dari setiap utas, saat mengirim komit ():

sqlalchemy.exc.InvalidRequestError: This transaction is inactive

Seperti yang saya baca di banyak tempat, scoped_session dimaksudkan untuk menjadi thread-safe, tetapi dari pengalaman saya itu tidak berfungsi.

0
Dor Shpindler 19 November 2020, 21:40

1 menjawab

Jawaban Terbaik

Rupanya, lokasi connect() yang menyebabkan perilaku ini. menghapus panggilan connect memecahkan masalah:

engine = create_engine(
    f'postgresql://postgres:{password}@{host}:5432/dbname',
    pool_pre_ping=True).execution_options(
    schema_translate_map={None: "my_db"})
Session = scoped_session(sessionmaker(bind=engine))
0
Dor Shpindler 19 November 2020, 19:40