@@ -704,10 +704,65 @@ async def test_database_url_interface(database_url):
704
704
@pytest .mark .parametrize ("database_url" , DATABASE_URLS )
705
705
@async_adapter
706
706
async 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
+
707
711
async with Database (database_url , force_rollback = True ) as database :
708
712
709
713
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)" )
712
715
713
716
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