@@ -704,10 +704,65 @@ async def test_database_url_interface(database_url):
704704@pytest .mark .parametrize ("database_url" , DATABASE_URLS )
705705@async_adapter
706706async def test_concurrent_access_on_single_connection (database_url ):
707+ database_url = DatabaseURL (database_url )
708+ if database_url .dialect != "postgresql" :
709+ pytest .skip ("Test requires `pg_sleep()`" )
710+
707711 async with Database (database_url , force_rollback = True ) as database :
708712
709713 async def db_lookup ():
710- if str (database_url ).startswith ("postgresql" ):
711- await database .fetch_one ("SELECT pg_sleep(1)" )
714+ await database .fetch_one ("SELECT pg_sleep(1)" )
712715
713716 await asyncio .gather (db_lookup (), db_lookup ())
717+
718+
719+ @pytest .mark .parametrize ("database_url" , DATABASE_URLS )
720+ @async_adapter
721+ async def test_iterate_outside_transaction_with_values (database_url ):
722+ """
723+ Ensure `iterate()` works even without a transaction on all drivers.
724+ The asyncpg driver relies on server-side cursors without hold
725+ for iteration, which requires a transaction to be created.
726+ This is mentionned in both their documentation and their test suite.
727+ """
728+
729+ database_url = DatabaseURL (database_url )
730+ if database_url .dialect == "mysql" :
731+ pytest .skip ("MySQL does not support `FROM (VALUES ...)` (F641)" )
732+
733+ async with Database (database_url ) as database :
734+ query = "SELECT * FROM (VALUES (1), (2), (3), (4), (5)) as t"
735+ iterate_results = []
736+
737+ async for result in database .iterate (query = query ):
738+ iterate_results .append (result )
739+
740+ assert len (iterate_results ) == 5
741+
742+
743+ @pytest .mark .parametrize ("database_url" , DATABASE_URLS )
744+ @async_adapter
745+ async def test_iterate_outside_transaction_with_temp_table (database_url ):
746+ """
747+ Same as test_iterate_outside_transaction_with_values but uses a
748+ temporary table instead of a list of values.
749+ """
750+
751+ database_url = DatabaseURL (database_url )
752+ if database_url .dialect == "sqlite" :
753+ pytest .skip ("SQLite interface does not work with temporary tables." )
754+
755+ async with Database (database_url ) as database :
756+ query = "CREATE TEMPORARY TABLE no_transac(num INTEGER)"
757+ await database .execute (query )
758+
759+ query = "INSERT INTO no_transac(num) VALUES (1), (2), (3), (4), (5)"
760+ await database .execute (query )
761+
762+ query = "SELECT * FROM no_transac"
763+ iterate_results = []
764+
765+ async for result in database .iterate (query = query ):
766+ iterate_results .append (result )
767+
768+ assert len (iterate_results ) == 5
0 commit comments