11from __future__ import annotations
22
33from collections .abc import Sequence
4- from typing import Any , Optional
4+ from typing import Any , Optional , cast
55
6- from piccolo .utils .lazy_loader import LazyLoader
7- from piccolo .utils .warnings import Level , colored_warning
6+ from .postgres import Atomic , PostgresEngine , PostgresTransaction
87
9- from .postgres import PostgresEngine
108
11- asyncpg = LazyLoader ("asyncpg" , globals (), "asyncpg" )
9+ class CockroachAtomic (Atomic ):
10+
11+ __slots__ = ("autocommit_before_ddl" ,)
12+
13+ def __init__ (
14+ self ,
15+ engine : CockroachEngine ,
16+ autocommit_before_ddl : Optional [bool ] = False ,
17+ ):
18+ """
19+ :param autocommit_before_ddl:
20+ Defaults to ``False`` to prevent automatic DDL commits
21+ in transactions (preventing rollbacks). Applies only to the current
22+ transaction and is automatically reverted when the transaction
23+ commits or is rolled back.
24+
25+ Usage::
26+
27+ # Defaults to ``False`` (``autocommit_before_ddl = off``)
28+ transaction = engine.atomic()
29+ transaction.add(Foo.create_table())
30+
31+ # If we want to set ``autocommit_before_ddl = on``,
32+ # which is the default Cockroach session setting.
33+ transaction = engine.atomic(autocommit_before_ddl=True)
34+ transaction.add(Foo.create_table())
35+
36+ """
37+ super ().__init__ (engine )
38+ self .autocommit_before_ddl = autocommit_before_ddl
39+
40+ async def setup_transaction (self , transaction : PostgresTransaction ):
41+ if self .autocommit_before_ddl is not None :
42+ transaction = cast (CockroachTransaction , transaction )
43+ await transaction .autocommit_before_ddl (
44+ enabled = self .autocommit_before_ddl
45+ )
46+
47+
48+ class CockroachTransaction (PostgresTransaction ):
49+
50+ async def autocommit_before_ddl (self , enabled : bool = True ):
51+ value = "on" if enabled else "off"
52+ await self .connection .execute (
53+ f"SET LOCAL autocommit_before_ddl = { value } "
54+ )
1255
1356
1457class CockroachEngine (PostgresEngine ):
@@ -35,15 +78,20 @@ def __init__(
3578 self .engine_type = "cockroach"
3679 self .min_version_number = 0
3780
38- async def prep_database (self ):
39- try :
40- await self ._run_in_new_connection (
41- "SET CLUSTER SETTING sql.defaults.experimental_alter_column_type.enabled = true;" # noqa: E501
42- )
43- except asyncpg .exceptions .InsufficientPrivilegeError :
44- colored_warning (
45- "=> Unable to set up Cockroach DB "
46- "functionality may not behave as expected. Make sure "
47- "your database user has permission to set cluster options." ,
48- level = Level .medium ,
49- )
81+ def atomic (
82+ self ,
83+ autocommit_before_ddl : Optional [bool ] = False ,
84+ ) -> CockroachAtomic :
85+ return CockroachAtomic (
86+ engine = self ,
87+ autocommit_before_ddl = autocommit_before_ddl ,
88+ )
89+
90+ def transaction (
91+ self ,
92+ allow_nested : bool = True ,
93+ ) -> CockroachTransaction :
94+ return CockroachTransaction (
95+ engine = self ,
96+ allow_nested = allow_nested ,
97+ )
0 commit comments