sqla-fancy-core 1.0.0__py3-none-any.whl → 1.2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sqla-fancy-core might be problematic. Click here for more details.
- sqla_fancy_core/__init__.py +9 -157
- sqla_fancy_core/decorators.py +196 -0
- sqla_fancy_core/factories.py +156 -0
- sqla_fancy_core/wrappers.py +439 -0
- sqla_fancy_core-1.2.2.dist-info/METADATA +486 -0
- sqla_fancy_core-1.2.2.dist-info/RECORD +8 -0
- sqla_fancy_core-1.0.0.dist-info/METADATA +0 -192
- sqla_fancy_core-1.0.0.dist-info/RECORD +0 -5
- {sqla_fancy_core-1.0.0.dist-info → sqla_fancy_core-1.2.2.dist-info}/WHEEL +0 -0
- {sqla_fancy_core-1.0.0.dist-info → sqla_fancy_core-1.2.2.dist-info}/licenses/LICENSE +0 -0
sqla_fancy_core/__init__.py
CHANGED
|
@@ -1,159 +1,11 @@
|
|
|
1
1
|
"""SQLAlchemy core, but fancier."""
|
|
2
2
|
|
|
3
|
-
from
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"""Initialize the factory with default values."""
|
|
13
|
-
if metadata is None:
|
|
14
|
-
metadata = sa.MetaData()
|
|
15
|
-
self.metadata = metadata
|
|
16
|
-
self.c = []
|
|
17
|
-
|
|
18
|
-
def col(self, *args, **kwargs) -> sa.Column:
|
|
19
|
-
col = sa.Column(*args, **kwargs)
|
|
20
|
-
self.c.append(col)
|
|
21
|
-
return col
|
|
22
|
-
|
|
23
|
-
def integer(self, name: str, *args, **kwargs) -> sa.Column:
|
|
24
|
-
return self.col(name, sa.Integer, *args, **kwargs)
|
|
25
|
-
|
|
26
|
-
def string(self, name: str, *args, **kwargs) -> sa.Column:
|
|
27
|
-
return self.col(name, sa.String, *args, **kwargs)
|
|
28
|
-
|
|
29
|
-
def text(self, name: str, *args, **kwargs) -> sa.Column:
|
|
30
|
-
return self.col(name, sa.Text, *args, **kwargs)
|
|
31
|
-
|
|
32
|
-
def float(self, name: str, *args, **kwargs) -> sa.Column:
|
|
33
|
-
return self.col(name, sa.Float, *args, **kwargs)
|
|
34
|
-
|
|
35
|
-
def numeric(self, name: str, *args, **kwargs) -> sa.Column:
|
|
36
|
-
return self.col(name, sa.Numeric, *args, **kwargs)
|
|
37
|
-
|
|
38
|
-
def bigint(self, name: str, *args, **kwargs) -> sa.Column:
|
|
39
|
-
return self.col(name, sa.BigInteger, *args, **kwargs)
|
|
40
|
-
|
|
41
|
-
def smallint(self, name: str, *args, **kwargs) -> sa.Column:
|
|
42
|
-
return self.col(name, sa.SmallInteger, *args, **kwargs)
|
|
43
|
-
|
|
44
|
-
def timestamp(self, name: str, *args, **kwargs) -> sa.Column:
|
|
45
|
-
return self.col(name, sa.TIMESTAMP, *args, **kwargs)
|
|
46
|
-
|
|
47
|
-
def date(self, name: str, *args, **kwargs) -> sa.Column:
|
|
48
|
-
return self.col(name, sa.Date, *args, **kwargs)
|
|
49
|
-
|
|
50
|
-
def datetime(self, name: str, *args, **kwargs) -> sa.Column:
|
|
51
|
-
return self.col(name, sa.DateTime, *args, **kwargs)
|
|
52
|
-
|
|
53
|
-
def today(self, name: str, *args, **kwargs) -> sa.Column:
|
|
54
|
-
return self.date(name, default=sa.func.now(), *args, **kwargs)
|
|
55
|
-
|
|
56
|
-
def time(self, name: str, *args, **kwargs) -> sa.Column:
|
|
57
|
-
return self.col(name, sa.Time, *args, **kwargs)
|
|
58
|
-
|
|
59
|
-
def timenow(self, name: str, *args, **kwargs) -> sa.Column:
|
|
60
|
-
return self.time(name, default=sa.func.now(), *args, **kwargs)
|
|
61
|
-
|
|
62
|
-
def now(self, name: str, *args, **kwargs) -> sa.Column:
|
|
63
|
-
return self.datetime(name, default=sa.func.now(), *args, **kwargs)
|
|
64
|
-
|
|
65
|
-
def boolean(self, name: str, *args, **kwargs) -> sa.Column:
|
|
66
|
-
return self.col(name, sa.Boolean, *args, **kwargs)
|
|
67
|
-
|
|
68
|
-
def true(self, name: str, *args, **kwargs):
|
|
69
|
-
return self.boolean(name, default=True, *args, **kwargs)
|
|
70
|
-
|
|
71
|
-
def false(self, name: str, *args, **kwargs):
|
|
72
|
-
return self.boolean(name, default=False, *args, **kwargs)
|
|
73
|
-
|
|
74
|
-
def foreign_key(self, name: str, ref: Union[str, sa.Column], *args, **kwargs):
|
|
75
|
-
return self.col(name, sa.ForeignKey(ref), *args, **kwargs)
|
|
76
|
-
|
|
77
|
-
def enum(self, name: str, enum: type, *args, **kwargs) -> sa.Column:
|
|
78
|
-
return self.col(name, sa.Enum(enum), *args, **kwargs)
|
|
79
|
-
|
|
80
|
-
def json(self, name: str, *args, **kwargs) -> sa.Column:
|
|
81
|
-
return self.col(name, sa.JSON, *args, **kwargs)
|
|
82
|
-
|
|
83
|
-
def array(self, name: str, *args, **kwargs) -> sa.Column:
|
|
84
|
-
return self.col(name, sa.ARRAY, *args, **kwargs)
|
|
85
|
-
|
|
86
|
-
def array_int(self, name: str, *args, **kwargs) -> sa.Column:
|
|
87
|
-
return self.array(name, sa.Integer, *args, **kwargs)
|
|
88
|
-
|
|
89
|
-
def array_str(self, name: str, *args, **kwargs) -> sa.Column:
|
|
90
|
-
return self.array(name, sa.String, *args, **kwargs)
|
|
91
|
-
|
|
92
|
-
def array_text(self, name: str, *args, **kwargs) -> sa.Column:
|
|
93
|
-
return self.array(name, sa.Text, *args, **kwargs)
|
|
94
|
-
|
|
95
|
-
def array_float(self, name: str, *args, **kwargs) -> sa.Column:
|
|
96
|
-
return self.array(name, sa.Float, *args, **kwargs)
|
|
97
|
-
|
|
98
|
-
def array_numeric(self, name: str, *args, **kwargs) -> sa.Column:
|
|
99
|
-
return self.array(name, sa.Numeric, *args, **kwargs)
|
|
100
|
-
|
|
101
|
-
def array_bigint(self, name: str, *args, **kwargs) -> sa.Column:
|
|
102
|
-
return self.array(name, sa.BigInteger, *args, **kwargs)
|
|
103
|
-
|
|
104
|
-
def array_smallint(self, name: str, *args, **kwargs) -> sa.Column:
|
|
105
|
-
return self.array(name, sa.SmallInteger, *args, **kwargs)
|
|
106
|
-
|
|
107
|
-
def array_timestamp(self, name: str, *args, **kwargs) -> sa.Column:
|
|
108
|
-
return self.array(name, sa.TIMESTAMP, *args, **kwargs)
|
|
109
|
-
|
|
110
|
-
def array_date(self, name: str, *args, **kwargs) -> sa.Column:
|
|
111
|
-
return self.array(name, sa.Date, *args, **kwargs)
|
|
112
|
-
|
|
113
|
-
def array_datetime(self, name: str, *args, **kwargs) -> sa.Column:
|
|
114
|
-
return self.array(name, sa.DateTime, *args, **kwargs)
|
|
115
|
-
|
|
116
|
-
def array_time(self, name: str, *args, **kwargs) -> sa.Column:
|
|
117
|
-
return self.array(name, sa.Time, *args, **kwargs)
|
|
118
|
-
|
|
119
|
-
def array_boolean(self, name: str, *args, **kwargs) -> sa.Column:
|
|
120
|
-
return self.array(name, sa.Boolean, *args, **kwargs)
|
|
121
|
-
|
|
122
|
-
def array_enum(self, name: str, enum: type, *args, **kwargs) -> sa.Column:
|
|
123
|
-
return self.array(name, sa.Enum(enum), *args, **kwargs)
|
|
124
|
-
|
|
125
|
-
def auto_id(self, name="id", *args, **kwargs) -> sa.Column:
|
|
126
|
-
return self.integer(
|
|
127
|
-
name, primary_key=True, index=True, autoincrement=True, *args, **kwargs
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
def updated_at(self, name="updated_at", *args, **kwargs) -> sa.Column:
|
|
131
|
-
return self.datetime(
|
|
132
|
-
name, default=sa.func.now(), onupdate=sa.func.now(), *args, **kwargs
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
def created_at(self, name="created_at", *args, **kwargs) -> sa.Column:
|
|
136
|
-
return self.datetime(name, default=sa.func.now(), *args, **kwargs)
|
|
137
|
-
|
|
138
|
-
@overload
|
|
139
|
-
def __call__(self, arg1: str, *args, **kwargs) -> sa.Table: ...
|
|
140
|
-
@overload
|
|
141
|
-
def __call__(self, arg1: sa.Column, *args, **kwargs) -> sa.Column: ...
|
|
142
|
-
@overload
|
|
143
|
-
def __call__(self, arg1: sa.Table, *args, **kwargs) -> sa.Table: ...
|
|
144
|
-
def __call__(self, arg1, *args, **kwargs):
|
|
145
|
-
if isinstance(arg1, str):
|
|
146
|
-
cols = self.c
|
|
147
|
-
self.c = []
|
|
148
|
-
return sa.Table(arg1, self.metadata, *args, *cols, **kwargs)
|
|
149
|
-
elif isinstance(arg1, sa.Column):
|
|
150
|
-
arg1.info["args"] = args
|
|
151
|
-
arg1.info["kwargs"] = kwargs
|
|
152
|
-
self.c.append(arg1)
|
|
153
|
-
return arg1
|
|
154
|
-
elif isinstance(arg1, sa.Table):
|
|
155
|
-
cols = self.c
|
|
156
|
-
self.c = []
|
|
157
|
-
return sa.Table(arg1.name, self.metadata, *args, *cols, **kwargs)
|
|
158
|
-
else:
|
|
159
|
-
raise TypeError(f"Expected a string or Column, got {type(arg1).__name__}")
|
|
3
|
+
from sqla_fancy_core.factories import TableFactory # noqa
|
|
4
|
+
from sqla_fancy_core.wrappers import ( # noqa
|
|
5
|
+
FancyEngineWrapper,
|
|
6
|
+
AsyncFancyEngineWrapper,
|
|
7
|
+
fancy,
|
|
8
|
+
FancyError,
|
|
9
|
+
AtomicContextError,
|
|
10
|
+
)
|
|
11
|
+
from sqla_fancy_core.decorators import transact, Inject # noqa
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"""Some decorators for fun times with SQLAlchemy core."""
|
|
2
|
+
|
|
3
|
+
import functools
|
|
4
|
+
import inspect
|
|
5
|
+
from typing import Union, overload
|
|
6
|
+
|
|
7
|
+
import sqlalchemy as sa
|
|
8
|
+
from sqlalchemy.ext.asyncio import AsyncConnection, AsyncEngine
|
|
9
|
+
|
|
10
|
+
from sqla_fancy_core.wrappers import AsyncFancyEngineWrapper, FancyEngineWrapper
|
|
11
|
+
|
|
12
|
+
EngineType = Union[sa.Engine, AsyncEngine, FancyEngineWrapper, AsyncFancyEngineWrapper]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class _Injectable:
|
|
16
|
+
def __init__(self, engine: EngineType):
|
|
17
|
+
self.engine = engine
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@overload
|
|
21
|
+
def Inject(engine: Union[sa.Engine, FancyEngineWrapper]) -> sa.Connection: ...
|
|
22
|
+
@overload
|
|
23
|
+
def Inject(engine: Union[AsyncEngine, AsyncFancyEngineWrapper]) -> AsyncConnection: ...
|
|
24
|
+
def Inject(engine: EngineType): # type: ignore
|
|
25
|
+
"""A marker class for dependency injection."""
|
|
26
|
+
return _Injectable(engine)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def transact(func):
|
|
30
|
+
"""A decorator that provides a transactional context.
|
|
31
|
+
|
|
32
|
+
If the decorated function is called with a connection object, that
|
|
33
|
+
connection is used. Otherwise, a new transaction is started from the
|
|
34
|
+
engine, and the new connection is injected to the function.
|
|
35
|
+
|
|
36
|
+
Example: ::
|
|
37
|
+
@transact
|
|
38
|
+
def create_user(name: str, conn: sa.Connection = Inject(engine)):
|
|
39
|
+
conn.execute(...)
|
|
40
|
+
|
|
41
|
+
# This will create a new transaction
|
|
42
|
+
create_user("test")
|
|
43
|
+
|
|
44
|
+
# This will use the existing connection
|
|
45
|
+
with engine.connect() as conn:
|
|
46
|
+
create_user(name="existing", conn=conn)
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
sig = inspect.signature(func)
|
|
50
|
+
inject_param_name = None
|
|
51
|
+
for name, param in sig.parameters.items():
|
|
52
|
+
if param.default is not inspect.Parameter.empty and isinstance(
|
|
53
|
+
param.default, _Injectable
|
|
54
|
+
):
|
|
55
|
+
inject_param_name = name
|
|
56
|
+
break
|
|
57
|
+
if inject_param_name is None:
|
|
58
|
+
return func # No injection needed
|
|
59
|
+
|
|
60
|
+
engine_arg = sig.parameters[inject_param_name].default.engine
|
|
61
|
+
if isinstance(engine_arg, sa.Engine):
|
|
62
|
+
is_async = False
|
|
63
|
+
engine = engine_arg
|
|
64
|
+
elif isinstance(engine_arg, FancyEngineWrapper):
|
|
65
|
+
is_async = False
|
|
66
|
+
engine = engine_arg.engine
|
|
67
|
+
elif isinstance(engine_arg, AsyncEngine):
|
|
68
|
+
is_async = True
|
|
69
|
+
engine = engine_arg
|
|
70
|
+
elif isinstance(engine_arg, AsyncFancyEngineWrapper):
|
|
71
|
+
is_async = True
|
|
72
|
+
engine = engine_arg.engine
|
|
73
|
+
else:
|
|
74
|
+
raise TypeError("Unsupported engine type")
|
|
75
|
+
|
|
76
|
+
if is_async:
|
|
77
|
+
|
|
78
|
+
@functools.wraps(func)
|
|
79
|
+
async def async_wrapper(*args, **kwargs):
|
|
80
|
+
conn = kwargs.get(inject_param_name)
|
|
81
|
+
if isinstance(conn, AsyncConnection):
|
|
82
|
+
if conn.in_transaction():
|
|
83
|
+
return await func(*args, **kwargs)
|
|
84
|
+
else:
|
|
85
|
+
async with conn.begin():
|
|
86
|
+
return await func(*args, **kwargs)
|
|
87
|
+
elif isinstance(conn, sa.Connection):
|
|
88
|
+
if conn.in_transaction():
|
|
89
|
+
return await func(*args, **kwargs)
|
|
90
|
+
else:
|
|
91
|
+
with conn.begin():
|
|
92
|
+
return await func(*args, **kwargs)
|
|
93
|
+
else:
|
|
94
|
+
async with engine.begin() as conn: # type: ignore
|
|
95
|
+
kwargs[inject_param_name] = conn
|
|
96
|
+
return await func(*args, **kwargs)
|
|
97
|
+
|
|
98
|
+
return async_wrapper
|
|
99
|
+
|
|
100
|
+
else:
|
|
101
|
+
|
|
102
|
+
@functools.wraps(func)
|
|
103
|
+
def sync_wrapper(*args, **kwargs):
|
|
104
|
+
conn = kwargs.get(inject_param_name)
|
|
105
|
+
if isinstance(conn, sa.Connection):
|
|
106
|
+
if conn.in_transaction():
|
|
107
|
+
return func(*args, **kwargs)
|
|
108
|
+
else:
|
|
109
|
+
with conn.begin():
|
|
110
|
+
return func(*args, **kwargs)
|
|
111
|
+
elif isinstance(conn, AsyncConnection):
|
|
112
|
+
raise TypeError("AsyncConnection cannot be used in sync function")
|
|
113
|
+
else:
|
|
114
|
+
with engine.begin() as conn: # type: ignore
|
|
115
|
+
kwargs[inject_param_name] = conn
|
|
116
|
+
return func(*args, **kwargs)
|
|
117
|
+
|
|
118
|
+
return sync_wrapper
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def connect(func):
|
|
122
|
+
"""A decorator that provides a connection context.
|
|
123
|
+
|
|
124
|
+
If the decorated function is called with a connection object, that
|
|
125
|
+
connection is used. Otherwise, a new connection is created from the
|
|
126
|
+
engine, and the new connection is injected to the function.
|
|
127
|
+
|
|
128
|
+
Example: ::
|
|
129
|
+
@connect
|
|
130
|
+
def get_user_count(conn: sa.Connection = Inject(engine)) -> int:
|
|
131
|
+
return conn.execute(...).scalar_one()
|
|
132
|
+
|
|
133
|
+
# This will create a new connection
|
|
134
|
+
count = get_user_count()
|
|
135
|
+
|
|
136
|
+
# This will use the existing connection
|
|
137
|
+
with engine.connect() as conn:
|
|
138
|
+
count = get_user_count(conn)
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
sig = inspect.signature(func)
|
|
142
|
+
inject_param_name = None
|
|
143
|
+
for name, param in sig.parameters.items():
|
|
144
|
+
if param.default is not inspect.Parameter.empty and isinstance(
|
|
145
|
+
param.default, _Injectable
|
|
146
|
+
):
|
|
147
|
+
inject_param_name = name
|
|
148
|
+
break
|
|
149
|
+
if inject_param_name is None:
|
|
150
|
+
return func # No injection needed
|
|
151
|
+
|
|
152
|
+
engine_arg = sig.parameters[inject_param_name].default.engine
|
|
153
|
+
if isinstance(engine_arg, sa.Engine):
|
|
154
|
+
is_async = False
|
|
155
|
+
engine = engine_arg
|
|
156
|
+
elif isinstance(engine_arg, FancyEngineWrapper):
|
|
157
|
+
is_async = False
|
|
158
|
+
engine = engine_arg.engine
|
|
159
|
+
elif isinstance(engine_arg, AsyncEngine):
|
|
160
|
+
is_async = True
|
|
161
|
+
engine = engine_arg
|
|
162
|
+
elif isinstance(engine_arg, AsyncFancyEngineWrapper):
|
|
163
|
+
is_async = True
|
|
164
|
+
engine = engine_arg.engine
|
|
165
|
+
else:
|
|
166
|
+
raise TypeError("Unsupported engine type")
|
|
167
|
+
|
|
168
|
+
if is_async:
|
|
169
|
+
|
|
170
|
+
@functools.wraps(func)
|
|
171
|
+
async def async_wrapper(*args, **kwargs):
|
|
172
|
+
conn = kwargs.get(inject_param_name)
|
|
173
|
+
if isinstance(conn, (AsyncConnection, sa.Connection)):
|
|
174
|
+
return await func(*args, **kwargs)
|
|
175
|
+
else:
|
|
176
|
+
async with engine.connect() as conn: # type: ignore
|
|
177
|
+
kwargs[inject_param_name] = conn
|
|
178
|
+
return await func(*args, **kwargs)
|
|
179
|
+
|
|
180
|
+
return async_wrapper
|
|
181
|
+
|
|
182
|
+
else:
|
|
183
|
+
|
|
184
|
+
@functools.wraps(func)
|
|
185
|
+
def sync_wrapper(*args, **kwargs):
|
|
186
|
+
conn = kwargs.get(inject_param_name)
|
|
187
|
+
if isinstance(conn, sa.Connection):
|
|
188
|
+
return func(*args, **kwargs)
|
|
189
|
+
elif isinstance(conn, AsyncConnection):
|
|
190
|
+
raise TypeError("AsyncConnection cannot be used in sync function")
|
|
191
|
+
else:
|
|
192
|
+
with engine.connect() as conn: # type: ignore
|
|
193
|
+
kwargs[inject_param_name] = conn
|
|
194
|
+
return func(*args, **kwargs)
|
|
195
|
+
|
|
196
|
+
return sync_wrapper
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"""Some factories for fun times with SQLAlchemy core."""
|
|
2
|
+
|
|
3
|
+
from typing import Optional, Union, overload
|
|
4
|
+
|
|
5
|
+
import sqlalchemy as sa
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TableFactory:
|
|
9
|
+
"""A factory for creating SQLAlchemy columns with default values."""
|
|
10
|
+
|
|
11
|
+
def __init__(self, metadata: Optional[sa.MetaData] = None):
|
|
12
|
+
"""Initialize the factory with default values."""
|
|
13
|
+
if metadata is None:
|
|
14
|
+
self.metadata = sa.MetaData()
|
|
15
|
+
else:
|
|
16
|
+
self.metadata = metadata
|
|
17
|
+
self.c = []
|
|
18
|
+
|
|
19
|
+
def col(self, *args, **kwargs) -> sa.Column:
|
|
20
|
+
col = sa.Column(*args, **kwargs)
|
|
21
|
+
return self(col)
|
|
22
|
+
|
|
23
|
+
def integer(self, name: str, *args, **kwargs) -> sa.Column:
|
|
24
|
+
return self.col(name, sa.Integer, *args, **kwargs)
|
|
25
|
+
|
|
26
|
+
def string(self, name: str, *args, **kwargs) -> sa.Column:
|
|
27
|
+
return self.col(name, sa.String, *args, **kwargs)
|
|
28
|
+
|
|
29
|
+
def text(self, name: str, *args, **kwargs) -> sa.Column:
|
|
30
|
+
return self.col(name, sa.Text, *args, **kwargs)
|
|
31
|
+
|
|
32
|
+
def float(self, name: str, *args, **kwargs) -> sa.Column:
|
|
33
|
+
return self.col(name, sa.Float, *args, **kwargs)
|
|
34
|
+
|
|
35
|
+
def numeric(self, name: str, *args, **kwargs) -> sa.Column:
|
|
36
|
+
return self.col(name, sa.Numeric, *args, **kwargs)
|
|
37
|
+
|
|
38
|
+
def bigint(self, name: str, *args, **kwargs) -> sa.Column:
|
|
39
|
+
return self.col(name, sa.BigInteger, *args, **kwargs)
|
|
40
|
+
|
|
41
|
+
def smallint(self, name: str, *args, **kwargs) -> sa.Column:
|
|
42
|
+
return self.col(name, sa.SmallInteger, *args, **kwargs)
|
|
43
|
+
|
|
44
|
+
def timestamp(self, name: str, *args, **kwargs) -> sa.Column:
|
|
45
|
+
return self.col(name, sa.TIMESTAMP, *args, **kwargs)
|
|
46
|
+
|
|
47
|
+
def date(self, name: str, *args, **kwargs) -> sa.Column:
|
|
48
|
+
return self.col(name, sa.Date, *args, **kwargs)
|
|
49
|
+
|
|
50
|
+
def datetime(self, name: str, *args, **kwargs) -> sa.Column:
|
|
51
|
+
return self.col(name, sa.DateTime, *args, **kwargs)
|
|
52
|
+
|
|
53
|
+
def today(self, name: str, *args, **kwargs) -> sa.Column:
|
|
54
|
+
return self.date(name, default=sa.func.now(), *args, **kwargs)
|
|
55
|
+
|
|
56
|
+
def time(self, name: str, *args, **kwargs) -> sa.Column:
|
|
57
|
+
return self.col(name, sa.Time, *args, **kwargs)
|
|
58
|
+
|
|
59
|
+
def timenow(self, name: str, *args, **kwargs) -> sa.Column:
|
|
60
|
+
return self.time(name, default=sa.func.now(), *args, **kwargs)
|
|
61
|
+
|
|
62
|
+
def now(self, name: str, *args, **kwargs) -> sa.Column:
|
|
63
|
+
return self.datetime(name, default=sa.func.now(), *args, **kwargs)
|
|
64
|
+
|
|
65
|
+
def boolean(self, name: str, *args, **kwargs) -> sa.Column:
|
|
66
|
+
return self.col(name, sa.Boolean, *args, **kwargs)
|
|
67
|
+
|
|
68
|
+
def true(self, name: str, *args, **kwargs):
|
|
69
|
+
return self.boolean(name, default=True, *args, **kwargs)
|
|
70
|
+
|
|
71
|
+
def false(self, name: str, *args, **kwargs):
|
|
72
|
+
return self.boolean(name, default=False, *args, **kwargs)
|
|
73
|
+
|
|
74
|
+
def foreign_key(self, name: str, ref: Union[str, sa.Column], *args, **kwargs):
|
|
75
|
+
return self.col(name, sa.ForeignKey(ref), *args, **kwargs)
|
|
76
|
+
|
|
77
|
+
def enum(self, name: str, enum: type, *args, **kwargs) -> sa.Column:
|
|
78
|
+
return self.col(name, sa.Enum(enum), *args, **kwargs)
|
|
79
|
+
|
|
80
|
+
def json(self, name: str, *args, **kwargs) -> sa.Column:
|
|
81
|
+
return self.col(name, sa.JSON, *args, **kwargs)
|
|
82
|
+
|
|
83
|
+
def array(self, name: str, *args, **kwargs) -> sa.Column:
|
|
84
|
+
return self.col(name, sa.ARRAY, *args, **kwargs)
|
|
85
|
+
|
|
86
|
+
def array_int(self, name: str, *args, **kwargs) -> sa.Column:
|
|
87
|
+
return self.array(name, sa.Integer, *args, **kwargs)
|
|
88
|
+
|
|
89
|
+
def array_str(self, name: str, *args, **kwargs) -> sa.Column:
|
|
90
|
+
return self.array(name, sa.String, *args, **kwargs)
|
|
91
|
+
|
|
92
|
+
def array_text(self, name: str, *args, **kwargs) -> sa.Column:
|
|
93
|
+
return self.array(name, sa.Text, *args, **kwargs)
|
|
94
|
+
|
|
95
|
+
def array_float(self, name: str, *args, **kwargs) -> sa.Column:
|
|
96
|
+
return self.array(name, sa.Float, *args, **kwargs)
|
|
97
|
+
|
|
98
|
+
def array_numeric(self, name: str, *args, **kwargs) -> sa.Column:
|
|
99
|
+
return self.array(name, sa.Numeric, *args, **kwargs)
|
|
100
|
+
|
|
101
|
+
def array_bigint(self, name: str, *args, **kwargs) -> sa.Column:
|
|
102
|
+
return self.array(name, sa.BigInteger, *args, **kwargs)
|
|
103
|
+
|
|
104
|
+
def array_smallint(self, name: str, *args, **kwargs) -> sa.Column:
|
|
105
|
+
return self.array(name, sa.SmallInteger, *args, **kwargs)
|
|
106
|
+
|
|
107
|
+
def array_timestamp(self, name: str, *args, **kwargs) -> sa.Column:
|
|
108
|
+
return self.array(name, sa.TIMESTAMP, *args, **kwargs)
|
|
109
|
+
|
|
110
|
+
def array_date(self, name: str, *args, **kwargs) -> sa.Column:
|
|
111
|
+
return self.array(name, sa.Date, *args, **kwargs)
|
|
112
|
+
|
|
113
|
+
def array_datetime(self, name: str, *args, **kwargs) -> sa.Column:
|
|
114
|
+
return self.array(name, sa.DateTime, *args, **kwargs)
|
|
115
|
+
|
|
116
|
+
def array_time(self, name: str, *args, **kwargs) -> sa.Column:
|
|
117
|
+
return self.array(name, sa.Time, *args, **kwargs)
|
|
118
|
+
|
|
119
|
+
def array_boolean(self, name: str, *args, **kwargs) -> sa.Column:
|
|
120
|
+
return self.array(name, sa.Boolean, *args, **kwargs)
|
|
121
|
+
|
|
122
|
+
def array_enum(self, name: str, enum: type, *args, **kwargs) -> sa.Column:
|
|
123
|
+
return self.array(name, sa.Enum(enum), *args, **kwargs)
|
|
124
|
+
|
|
125
|
+
def auto_id(self, name="id", *args, **kwargs) -> sa.Column:
|
|
126
|
+
return self.integer(
|
|
127
|
+
name, primary_key=True, index=True, autoincrement=True, *args, **kwargs
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
def updated_at(self, name="updated_at", *args, **kwargs) -> sa.Column:
|
|
131
|
+
return self.datetime(
|
|
132
|
+
name, default=sa.func.now(), onupdate=sa.func.now(), *args, **kwargs
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
def created_at(self, name="created_at", *args, **kwargs) -> sa.Column:
|
|
136
|
+
return self.datetime(name, default=sa.func.now(), *args, **kwargs)
|
|
137
|
+
|
|
138
|
+
@overload
|
|
139
|
+
def __call__(self, arg1: str, *args, **kwargs) -> sa.Table: ...
|
|
140
|
+
@overload
|
|
141
|
+
def __call__(self, arg1: sa.Column, *args, **kwargs) -> sa.Column: ...
|
|
142
|
+
@overload
|
|
143
|
+
def __call__(self, arg1: sa.Table, *args, **kwargs) -> sa.Table: ...
|
|
144
|
+
def __call__(self, arg1, *args, **kwargs):
|
|
145
|
+
if isinstance(arg1, sa.Column):
|
|
146
|
+
arg1.info["args"] = args
|
|
147
|
+
arg1.info["kwargs"] = kwargs
|
|
148
|
+
self.c.append(arg1)
|
|
149
|
+
return arg1
|
|
150
|
+
elif isinstance(arg1, Union[str, sa.Table]):
|
|
151
|
+
cols = self.c
|
|
152
|
+
tablename = arg1.name if isinstance(arg1, sa.Table) else arg1
|
|
153
|
+
self.c = []
|
|
154
|
+
return sa.Table(tablename, self.metadata, *args, *cols, **kwargs)
|
|
155
|
+
else:
|
|
156
|
+
raise TypeError(f"Expected a string or Column, got {type(arg1).__name__}")
|