I am attempting to load a table using sqlalchemy asyncio. The synchronous way I would run it is as follows:
connect_string = 'db_handle://user:password@db_address:port/database'
# where db_handle is postgressql psycopg2
engine = create_engine(connect_string)
table = Table(table, metadata, autoload=True, autoload_with=engine)
None of the solutions I implemented allow me (sqlalchemy core user) to load my table object to then use for querying (ie stmt=select([table.c.col])
I have attempted the following:
connect_string = 'db_handle://user:password@db_address:port/database'
# where db_handle is postgressql asyncpg
engine = create_async_engine(connect_string, echo=True)
metadata = MetaData()
#try 1
table = await Table(table, metadata, autoload=True, autoload_with=engine)
# error 1: sqlalchemy.exc.NoInspectionAvailable: Inspection on an AsyncEngine is currently not supported. Please obtain a connection then use ``conn.run_sync`` to pass a callable where it's possible to call ``inspect`` on the passed connection. (Background on this error at: https://sqlalche.me/e/14/xd3s)
#try 2
metadata.bind(db_engine_object)
table = await Table(table, metadata, autoload=True)
# error 2: TypeError: 'NoneType' object is not callable
#try 3
connection = db_engine_object.connect()
table = await Table(table, metadata, autoload=True, autoload_with=connection)
# error 3: sqlalchemy.exc.NoInspectionAvailable: Inspection on an AsyncConnection is currently not supported. Please use ``run_sync`` to pass a callable where it's possible to call ``inspect`` on the passed connection. (Background on this error at: https://sqlalche.me/e/14/xd3s)
#try 4
connection = db_engine_object.connect()
table = await Table(table, metadata, autoload=True, autoload_with=connection.run_sync())
# error 4: TypeError: run_sync() missing 1 required positional argument: 'fn'
I can't run a query without having a table to direct the query to, and I can't find out how to get the table object.
CodePudding user response:
This works for me. The lambda
inside run_sync
creates a function that run_sync
can call. Credit to @zzzeek's answer to this discussion on GitHub.
import asyncio
import sqlalchemy as sa
from sqlalchemy.ext.asyncio import create_async_engine
async def async_main():
engine = create_async_engine(
"postgresql asyncpg:///test",
echo=True,
)
async with engine.begin() as conn:
tbl = await conn.run_sync(
lambda conn: sa.Table('users', sa.MetaData(), autoload_with=conn)
)
async with engine.connect() as conn:
# select a Result, which will be delivered with buffered
# results
result = await conn.execute(sa.select(tbl))
print(result.fetchall())
# for AsyncEngine created in function scope, close and
# clean-up pooled connections
await engine.dispose()
asyncio.run(async_main())