ormlambda 3.12.2__py3-none-any.whl → 3.34.1__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.
- ormlambda/__init__.py +2 -0
- ormlambda/caster/__init__.py +1 -1
- ormlambda/caster/caster.py +29 -12
- ormlambda/common/abstract_classes/clause_info_converter.py +4 -12
- ormlambda/common/abstract_classes/decomposition_query.py +17 -2
- ormlambda/common/abstract_classes/non_query_base.py +9 -7
- ormlambda/common/abstract_classes/query_base.py +3 -1
- ormlambda/common/errors/__init__.py +29 -0
- ormlambda/common/interfaces/IQueryCommand.py +6 -2
- ormlambda/databases/__init__.py +0 -1
- ormlambda/databases/my_sql/__init__.py +0 -1
- ormlambda/databases/my_sql/caster/caster.py +23 -19
- ormlambda/databases/my_sql/caster/types/__init__.py +3 -0
- ormlambda/databases/my_sql/caster/types/boolean.py +35 -0
- ormlambda/databases/my_sql/caster/types/bytes.py +7 -7
- ormlambda/databases/my_sql/caster/types/date.py +34 -0
- ormlambda/databases/my_sql/caster/types/datetime.py +7 -7
- ormlambda/databases/my_sql/caster/types/decimal.py +32 -0
- ormlambda/databases/my_sql/caster/types/float.py +7 -7
- ormlambda/databases/my_sql/caster/types/int.py +7 -7
- ormlambda/databases/my_sql/caster/types/iterable.py +7 -7
- ormlambda/databases/my_sql/caster/types/none.py +8 -7
- ormlambda/databases/my_sql/caster/types/point.py +4 -4
- ormlambda/databases/my_sql/caster/types/string.py +7 -7
- ormlambda/databases/my_sql/clauses/ST_AsText.py +8 -7
- ormlambda/databases/my_sql/clauses/ST_Contains.py +10 -5
- ormlambda/databases/my_sql/clauses/__init__.py +4 -10
- ormlambda/databases/my_sql/clauses/count.py +5 -15
- ormlambda/databases/my_sql/clauses/delete.py +3 -50
- ormlambda/databases/my_sql/clauses/group_by.py +3 -16
- ormlambda/databases/my_sql/clauses/having.py +2 -6
- ormlambda/databases/my_sql/clauses/insert.py +4 -92
- ormlambda/databases/my_sql/clauses/joins.py +5 -140
- ormlambda/databases/my_sql/clauses/limit.py +4 -15
- ormlambda/databases/my_sql/clauses/offset.py +4 -15
- ormlambda/databases/my_sql/clauses/order.py +4 -61
- ormlambda/databases/my_sql/clauses/update.py +4 -67
- ormlambda/databases/my_sql/clauses/upsert.py +3 -66
- ormlambda/databases/my_sql/clauses/where.py +4 -42
- ormlambda/databases/my_sql/repository.py +217 -0
- ormlambda/dialects/__init__.py +39 -0
- ormlambda/dialects/default/__init__.py +1 -0
- ormlambda/dialects/default/base.py +39 -0
- ormlambda/dialects/interface/__init__.py +1 -0
- ormlambda/dialects/interface/dialect.py +78 -0
- ormlambda/dialects/mysql/__init__.py +8 -0
- ormlambda/dialects/mysql/base.py +387 -0
- ormlambda/dialects/mysql/mysqlconnector.py +46 -0
- ormlambda/dialects/mysql/types.py +732 -0
- ormlambda/dialects/sqlite/__init__.py +5 -0
- ormlambda/dialects/sqlite/base.py +47 -0
- ormlambda/dialects/sqlite/pysqlite.py +32 -0
- ormlambda/engine/__init__.py +1 -0
- ormlambda/engine/base.py +58 -0
- ormlambda/engine/create.py +9 -23
- ormlambda/engine/url.py +31 -19
- ormlambda/env.py +30 -0
- ormlambda/errors.py +17 -0
- ormlambda/model/base_model.py +7 -9
- ormlambda/repository/base_repository.py +36 -5
- ormlambda/repository/interfaces/IRepositoryBase.py +121 -7
- ormlambda/repository/response.py +134 -0
- ormlambda/sql/clause_info/aggregate_function_base.py +19 -9
- ormlambda/sql/clause_info/clause_info.py +34 -17
- ormlambda/sql/clauses/__init__.py +14 -0
- ormlambda/{databases/my_sql → sql}/clauses/alias.py +23 -6
- ormlambda/sql/clauses/count.py +57 -0
- ormlambda/sql/clauses/delete.py +71 -0
- ormlambda/sql/clauses/group_by.py +30 -0
- ormlambda/sql/clauses/having.py +21 -0
- ormlambda/sql/clauses/insert.py +104 -0
- ormlambda/sql/clauses/interfaces/__init__.py +5 -0
- ormlambda/{components → sql/clauses}/join/join_context.py +15 -7
- ormlambda/sql/clauses/joins.py +159 -0
- ormlambda/sql/clauses/limit.py +15 -0
- ormlambda/sql/clauses/offset.py +15 -0
- ormlambda/sql/clauses/order.py +55 -0
- ormlambda/{databases/my_sql → sql}/clauses/select.py +12 -13
- ormlambda/sql/clauses/update.py +84 -0
- ormlambda/sql/clauses/upsert.py +77 -0
- ormlambda/sql/clauses/where.py +65 -0
- ormlambda/sql/column/__init__.py +1 -0
- ormlambda/sql/{column.py → column/column.py} +82 -22
- ormlambda/sql/comparer.py +51 -37
- ormlambda/sql/compiler.py +427 -0
- ormlambda/sql/ddl.py +68 -0
- ormlambda/sql/elements.py +36 -0
- ormlambda/sql/foreign_key.py +43 -39
- ormlambda/{databases/my_sql → sql}/functions/concat.py +13 -5
- ormlambda/{databases/my_sql → sql}/functions/max.py +9 -4
- ormlambda/{databases/my_sql → sql}/functions/min.py +9 -13
- ormlambda/{databases/my_sql → sql}/functions/sum.py +8 -10
- ormlambda/sql/sqltypes.py +647 -0
- ormlambda/sql/table/__init__.py +1 -1
- ormlambda/sql/table/table.py +179 -0
- ormlambda/sql/table/table_constructor.py +1 -208
- ormlambda/sql/type_api.py +35 -0
- ormlambda/sql/types.py +3 -1
- ormlambda/sql/visitors.py +74 -0
- ormlambda/statements/__init__.py +1 -0
- ormlambda/statements/base_statement.py +28 -38
- ormlambda/statements/interfaces/IStatements.py +5 -4
- ormlambda/{databases/my_sql → statements}/query_builder.py +35 -30
- ormlambda/{databases/my_sql → statements}/statements.py +50 -60
- ormlambda/statements/types.py +2 -2
- ormlambda/types/__init__.py +24 -0
- ormlambda/types/metadata.py +42 -0
- ormlambda/util/__init__.py +88 -0
- ormlambda/util/load_module.py +21 -0
- ormlambda/util/plugin_loader.py +32 -0
- ormlambda/util/typing.py +6 -0
- ormlambda-3.34.1.dist-info/AUTHORS +32 -0
- {ormlambda-3.12.2.dist-info → ormlambda-3.34.1.dist-info}/METADATA +2 -3
- ormlambda-3.34.1.dist-info/RECORD +157 -0
- {ormlambda-3.12.2.dist-info → ormlambda-3.34.1.dist-info}/WHEEL +1 -1
- ormlambda/components/__init__.py +0 -4
- ormlambda/components/delete/__init__.py +0 -2
- ormlambda/components/delete/abstract_delete.py +0 -17
- ormlambda/components/insert/__init__.py +0 -2
- ormlambda/components/insert/abstract_insert.py +0 -25
- ormlambda/components/select/__init__.py +0 -1
- ormlambda/components/update/__init__.py +0 -2
- ormlambda/components/update/abstract_update.py +0 -29
- ormlambda/components/upsert/__init__.py +0 -2
- ormlambda/components/upsert/abstract_upsert.py +0 -25
- ormlambda/databases/my_sql/clauses/create_database.py +0 -35
- ormlambda/databases/my_sql/clauses/drop_database.py +0 -17
- ormlambda/databases/my_sql/repository/__init__.py +0 -1
- ormlambda/databases/my_sql/repository/repository.py +0 -351
- ormlambda/engine/template.py +0 -47
- ormlambda/sql/dtypes.py +0 -94
- ormlambda/utils/__init__.py +0 -1
- ormlambda-3.12.2.dist-info/RECORD +0 -125
- /ormlambda/databases/my_sql/{types.py → pool_types.py} +0 -0
- /ormlambda/{components/delete → sql/clauses/interfaces}/IDelete.py +0 -0
- /ormlambda/{components/insert → sql/clauses/interfaces}/IInsert.py +0 -0
- /ormlambda/{components/select → sql/clauses/interfaces}/ISelect.py +0 -0
- /ormlambda/{components/update → sql/clauses/interfaces}/IUpdate.py +0 -0
- /ormlambda/{components/upsert → sql/clauses/interfaces}/IUpsert.py +0 -0
- /ormlambda/{components → sql/clauses}/join/__init__.py +0 -0
- /ormlambda/{databases/my_sql → sql}/functions/__init__.py +0 -0
- /ormlambda/{utils → util}/module_tree/__init__.py +0 -0
- /ormlambda/{utils → util}/module_tree/dfs_traversal.py +0 -0
- /ormlambda/{utils → util}/module_tree/dynamic_module.py +0 -0
- {ormlambda-3.12.2.dist-info → ormlambda-3.34.1.dist-info}/LICENSE +0 -0
@@ -0,0 +1,387 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from types import ModuleType
|
3
|
+
from ormlambda.sql import compiler
|
4
|
+
from .. import default
|
5
|
+
from typing import TYPE_CHECKING, Any, Iterable
|
6
|
+
|
7
|
+
if TYPE_CHECKING:
|
8
|
+
from ormlambda.sql.column.column import Column
|
9
|
+
from mysql import connector
|
10
|
+
|
11
|
+
from .types import (
|
12
|
+
_NumericType,
|
13
|
+
_StringType,
|
14
|
+
NUMERIC,
|
15
|
+
DECIMAL,
|
16
|
+
DOUBLE,
|
17
|
+
REAL,
|
18
|
+
FLOAT,
|
19
|
+
INTEGER,
|
20
|
+
BIGINT,
|
21
|
+
MEDIUMINT,
|
22
|
+
TINYINT,
|
23
|
+
SMALLINT,
|
24
|
+
BIT,
|
25
|
+
TIME,
|
26
|
+
TIMESTAMP,
|
27
|
+
DATETIME,
|
28
|
+
YEAR,
|
29
|
+
TEXT,
|
30
|
+
TINYTEXT,
|
31
|
+
MEDIUMTEXT,
|
32
|
+
LONGTEXT,
|
33
|
+
NVARCHAR,
|
34
|
+
NCHAR,
|
35
|
+
TINYBLOB,
|
36
|
+
MEDIUMBLOB,
|
37
|
+
LONGBLOB,
|
38
|
+
)
|
39
|
+
from ormlambda.sql.sqltypes import BLOB
|
40
|
+
|
41
|
+
from ormlambda.databases.my_sql import MySQLRepository, MySQLCaster
|
42
|
+
|
43
|
+
|
44
|
+
if TYPE_CHECKING:
|
45
|
+
from ormlambda.sql.clauses import (
|
46
|
+
Select,
|
47
|
+
Insert,
|
48
|
+
Delete,
|
49
|
+
Upsert,
|
50
|
+
Update,
|
51
|
+
Limit,
|
52
|
+
Offset,
|
53
|
+
Count,
|
54
|
+
Where,
|
55
|
+
Having,
|
56
|
+
Order,
|
57
|
+
GroupBy,
|
58
|
+
)
|
59
|
+
|
60
|
+
from ormlambda.sql.functions import (
|
61
|
+
Concat,
|
62
|
+
Max,
|
63
|
+
Min,
|
64
|
+
Sum,
|
65
|
+
)
|
66
|
+
|
67
|
+
|
68
|
+
from ormlambda.sql.clause_info.clause_info_context import ClauseInfoContext
|
69
|
+
|
70
|
+
|
71
|
+
class MySQLCompiler(compiler.SQLCompiler):
|
72
|
+
render_table_with_column_in_update_from = True
|
73
|
+
"""Overridden from base SQLCompiler value"""
|
74
|
+
|
75
|
+
def visit_select(self, select: Select, **kw):
|
76
|
+
return f"{select.CLAUSE} {select.COLUMNS} FROM {select.FROM.query(self.dialect,**kw)}"
|
77
|
+
|
78
|
+
def visit_group_by(self, groupby: GroupBy, **kw):
|
79
|
+
column = groupby._create_query(self.dialect, **kw)
|
80
|
+
return f"{groupby.FUNCTION_NAME()} {column}"
|
81
|
+
|
82
|
+
def visit_limit(self, limit: Limit, **kw):
|
83
|
+
return f"{limit.LIMIT} {limit._number}"
|
84
|
+
|
85
|
+
# TODOH []: include the rest of visit methods
|
86
|
+
def visit_insert(self, insert: Insert, **kw) -> Insert: ...
|
87
|
+
def visit_delete(self, delete: Delete, **kw) -> Delete: ...
|
88
|
+
def visit_upsert(self, upsert: Upsert, **kw) -> Upsert: ...
|
89
|
+
def visit_update(self, update: Update, **kw) -> Update: ...
|
90
|
+
def visit_offset(self, offset: Offset, **kw) -> Offset:
|
91
|
+
return f"{offset.OFFSET} {offset._number}"
|
92
|
+
|
93
|
+
def visit_count(self, count: Count, **kw) -> Count: ...
|
94
|
+
def visit_where(self, where: Where, **kw) -> Where: ...
|
95
|
+
def visit_having(self, having: Having, **kw) -> Having: ...
|
96
|
+
def visit_order(self, order: Order, **kw) -> Order:
|
97
|
+
string_columns: list[str] = []
|
98
|
+
columns = order.unresolved_column
|
99
|
+
|
100
|
+
# if this attr is not iterable means that we only pass one column without wrapped in a list or tuple
|
101
|
+
if isinstance(columns, str):
|
102
|
+
string_columns = f"{columns} {str(order._order_type[0])}"
|
103
|
+
return f"{order.FUNCTION_NAME()} {string_columns}"
|
104
|
+
|
105
|
+
if not isinstance(columns, Iterable):
|
106
|
+
columns = (columns,)
|
107
|
+
|
108
|
+
assert len(columns) == len(order._order_type)
|
109
|
+
|
110
|
+
context = ClauseInfoContext(table_context=order._context._table_context, clause_context=None) if order._context else None
|
111
|
+
for index, clause in enumerate(order._convert_into_clauseInfo(columns, context, dialect=self.dialect)):
|
112
|
+
clause.alias_clause = None
|
113
|
+
string_columns.append(f"{clause.query(self.dialect,**kw)} {str(order._order_type[index])}")
|
114
|
+
|
115
|
+
return f"{order.FUNCTION_NAME()} {', '.join(string_columns)}"
|
116
|
+
|
117
|
+
def visit_concat(self, concat: Concat, **kw) -> Concat: ...
|
118
|
+
def visit_max(self, max: Max, **kw) -> Max: ...
|
119
|
+
def visit_min(self, min: Min, **kw) -> Min: ...
|
120
|
+
def visit_sum(self, sum: Sum, **kw) -> Sum: ...
|
121
|
+
|
122
|
+
|
123
|
+
class MySQLDDLCompiler(compiler.DDLCompiler):
|
124
|
+
def get_column_specification(self, column: Column, **kwargs):
|
125
|
+
colspec = column.column_name + " " + self.dialect.type_compiler_instance.process(column.dtype)
|
126
|
+
default = self.get_column_default_string(column)
|
127
|
+
if default is not None:
|
128
|
+
colspec += " DEFAULT " + default
|
129
|
+
|
130
|
+
if column.is_not_null:
|
131
|
+
colspec += " NOT NULL"
|
132
|
+
|
133
|
+
if column.is_primary_key:
|
134
|
+
colspec += " PRIMARY KEY"
|
135
|
+
|
136
|
+
colspec += " AUTO_INCREMENT" if column.is_auto_increment else ""
|
137
|
+
|
138
|
+
return colspec
|
139
|
+
|
140
|
+
|
141
|
+
class MySQLTypeCompiler(compiler.GenericTypeCompiler):
|
142
|
+
def mysql_type(self, type_: Any) -> bool:
|
143
|
+
return isinstance(type_, (_StringType, _NumericType))
|
144
|
+
|
145
|
+
def _extend_numeric(self, type_: _NumericType, spec: str) -> str:
|
146
|
+
"Extend a numeric-type declaration with MySQL specific extensions."
|
147
|
+
|
148
|
+
if not self.mysql_type(type_):
|
149
|
+
return spec
|
150
|
+
|
151
|
+
if type_.unsigned:
|
152
|
+
spec += " UNSIGNED"
|
153
|
+
if type_.zerofill:
|
154
|
+
spec += " ZEROFILL"
|
155
|
+
return spec
|
156
|
+
|
157
|
+
def _extend_string(self, type_: _StringType, defaults, spec):
|
158
|
+
"""Extend a string-type declaration with standard SQL CHARACTER SET /
|
159
|
+
COLLATE annotations and MySQL specific extensions.
|
160
|
+
|
161
|
+
"""
|
162
|
+
|
163
|
+
def attr(name):
|
164
|
+
return getattr(type_, name, defaults.get(name))
|
165
|
+
|
166
|
+
if attr("charset"):
|
167
|
+
charset = f"CHARACTER SET {attr("charset")}"
|
168
|
+
elif attr("ascii"):
|
169
|
+
charset = "ASCII"
|
170
|
+
elif attr("unicode"):
|
171
|
+
charset = "UNICODE"
|
172
|
+
else:
|
173
|
+
charset = None
|
174
|
+
|
175
|
+
if attr("collation"):
|
176
|
+
collation = f"COLLATE {type_.collation}"
|
177
|
+
elif attr("binary"):
|
178
|
+
collation = "BINARY"
|
179
|
+
else:
|
180
|
+
collation = None
|
181
|
+
|
182
|
+
if attr("national"):
|
183
|
+
# NATIONAL (aka NCHAR/NVARCHAR) trumps charsets.
|
184
|
+
return " ".join([c for c in ("NATIONAL", spec, collation) if c is not None])
|
185
|
+
return " ".join([c for c in (spec, charset, collation) if c is not None])
|
186
|
+
|
187
|
+
def visit_INTEGER(self, type_: INTEGER, **kw):
|
188
|
+
if self.mysql_type(type_) and type_.display_width is not None:
|
189
|
+
return self._extend_numeric(
|
190
|
+
type_,
|
191
|
+
f"INTEGER(%({type_.display_width})s)",
|
192
|
+
)
|
193
|
+
else:
|
194
|
+
return self._extend_numeric(type_, "INTEGER")
|
195
|
+
|
196
|
+
def visit_VARCHAR(self, type_, **kw):
|
197
|
+
if type_.length is None:
|
198
|
+
raise ValueError("VARCHAR requires a length on dialect %s" % self.dialect.name)
|
199
|
+
return self._extend_string(type_, {}, "VARCHAR(%d)" % type_.length)
|
200
|
+
|
201
|
+
def visit_CHAR(self, type_, **kw):
|
202
|
+
if type_.length is not None:
|
203
|
+
return self._extend_string(type_, {}, "CHAR(%(length)s)" % {"length": type_.length})
|
204
|
+
else:
|
205
|
+
return self._extend_string(type_, {}, "CHAR")
|
206
|
+
|
207
|
+
def visit_NUMERIC(self, type_: NUMERIC, **kw):
|
208
|
+
return "NUMERIC"
|
209
|
+
|
210
|
+
def visit_DECIMAL(self, type_: DECIMAL, **kw):
|
211
|
+
return "DECIMAL"
|
212
|
+
|
213
|
+
def visit_DOUBLE(self, type_: DOUBLE, **kw):
|
214
|
+
return "DOUBLE"
|
215
|
+
|
216
|
+
def visit_REAL(self, type_: REAL, **kw):
|
217
|
+
return "REAL"
|
218
|
+
|
219
|
+
def visit_FLOAT(self, type_: FLOAT, **kw):
|
220
|
+
return "FLOAT"
|
221
|
+
|
222
|
+
def visit_BIGINT(self, type_: BIGINT, **kw):
|
223
|
+
return "BIGINT"
|
224
|
+
|
225
|
+
def visit_MEDIUMINT(self, type_: MEDIUMINT, **kw):
|
226
|
+
return "MEDIUMINT"
|
227
|
+
|
228
|
+
def visit_TINYINT(self, type_: TINYINT, **kw):
|
229
|
+
return "TINYINT"
|
230
|
+
|
231
|
+
def visit_SMALLINT(self, type_: SMALLINT, **kw):
|
232
|
+
return "SMALLINT"
|
233
|
+
|
234
|
+
def visit_BIT(self, type_: BIT, **kw):
|
235
|
+
return "BIT"
|
236
|
+
|
237
|
+
def visit_TIME(self, type_: TIME, **kw):
|
238
|
+
return "TIME"
|
239
|
+
|
240
|
+
def visit_TIMESTAMP(self, type_: TIMESTAMP, **kw):
|
241
|
+
return "TIMESTAMP"
|
242
|
+
|
243
|
+
def visit_DATETIME(self, type_: DATETIME, **kw):
|
244
|
+
return "DATETIME"
|
245
|
+
|
246
|
+
def visit_YEAR(self, type_: YEAR, **kw):
|
247
|
+
return "YEAR"
|
248
|
+
|
249
|
+
def visit_TEXT(self, type_: TEXT, **kw):
|
250
|
+
if type_.length is not None:
|
251
|
+
return self._extend_string(type_, {}, f"TEXT({type_.length})")
|
252
|
+
return self._extend_string(type_, {}, "TEXT")
|
253
|
+
|
254
|
+
def visit_TINYTEXT(self, type_: TINYTEXT, **kw):
|
255
|
+
return "TINYTEXT"
|
256
|
+
|
257
|
+
def visit_MEDIUMTEXT(self, type_: MEDIUMTEXT, **kw):
|
258
|
+
return "MEDIUMTEXT"
|
259
|
+
|
260
|
+
def visit_LONGTEXT(self, type_: LONGTEXT, **kw):
|
261
|
+
return "LONGTEXT"
|
262
|
+
|
263
|
+
def visit_NVARCHAR(self, type_: NVARCHAR, **kw):
|
264
|
+
return "NVARCHAR"
|
265
|
+
|
266
|
+
def visit_NCHAR(self, type_: NCHAR, **kw):
|
267
|
+
return "NCHAR"
|
268
|
+
|
269
|
+
def visit_TINYBLOB(self, type_: TINYBLOB, **kw):
|
270
|
+
return "TINYBLOB"
|
271
|
+
|
272
|
+
def visit_BLOB(self, type_: BLOB, **kw) -> str:
|
273
|
+
blob = "BLOB"
|
274
|
+
blob += f"({type_.length})" if type_.length is not None else ""
|
275
|
+
return blob
|
276
|
+
|
277
|
+
def visit_MEDIUMBLOB(self, type_: MEDIUMBLOB, **kw):
|
278
|
+
return "MEDIUMBLOB"
|
279
|
+
|
280
|
+
def visit_LONGBLOB(self, type_: LONGBLOB, **kw):
|
281
|
+
return "LONGBLOB"
|
282
|
+
|
283
|
+
# region visit lowercase
|
284
|
+
|
285
|
+
def visit_integer(self, type_: INTEGER, **kw):
|
286
|
+
return self.visit_INTEGER(type_, **kw)
|
287
|
+
|
288
|
+
def visit_varchar(self, type_, **kw):
|
289
|
+
return self.visit_VARCHAR(type_, **kw)
|
290
|
+
|
291
|
+
def visit_char(self, type_, **kw):
|
292
|
+
return self.visit_CHAR(type_, **kw)
|
293
|
+
|
294
|
+
def visit_numeric(self, type_: NUMERIC, **kw):
|
295
|
+
return self.visit_NUMERIC(type_, **kw)
|
296
|
+
|
297
|
+
def visit_decimal(self, type_: DECIMAL, **kw):
|
298
|
+
return self.visit_DECIMAL(type_, **kw)
|
299
|
+
|
300
|
+
def visit_double(self, type_: DOUBLE, **kw):
|
301
|
+
return self.visit_DOUBLE(type_, **kw)
|
302
|
+
|
303
|
+
def visit_real(self, type_: REAL, **kw):
|
304
|
+
return self.visit_REAL(type_, **kw)
|
305
|
+
|
306
|
+
def visit_float(self, type_: FLOAT, **kw):
|
307
|
+
return self.visit_FLOAT(type_, **kw)
|
308
|
+
|
309
|
+
def visit_bigint(self, type_: BIGINT, **kw):
|
310
|
+
return self.visit_BIGINT(type_, **kw)
|
311
|
+
|
312
|
+
def visit_mediumint(self, type_: MEDIUMINT, **kw):
|
313
|
+
return self.visit_MEDIUMINT(type_, **kw)
|
314
|
+
|
315
|
+
def visit_tinyint(self, type_: TINYINT, **kw):
|
316
|
+
return self.visit_TINYINT(type_, **kw)
|
317
|
+
|
318
|
+
def visit_smallint(self, type_: SMALLINT, **kw):
|
319
|
+
return self.visit_SMALLINT(type_, **kw)
|
320
|
+
|
321
|
+
def visit_bit(self, type_: BIT, **kw):
|
322
|
+
return self.visit_BIT(type_, **kw)
|
323
|
+
|
324
|
+
def visit_time(self, type_: TIME, **kw):
|
325
|
+
return self.visit_TIME(type_, **kw)
|
326
|
+
|
327
|
+
def visit_timestamp(self, type_: TIMESTAMP, **kw):
|
328
|
+
return self.visit_TIMESTAMP(type_, **kw)
|
329
|
+
|
330
|
+
def visit_datetime(self, type_: DATETIME, **kw):
|
331
|
+
return self.visit_DATETIME(type_, **kw)
|
332
|
+
|
333
|
+
def visit_year(self, type_: YEAR, **kw):
|
334
|
+
return self.visit_YEAR(type_, **kw)
|
335
|
+
|
336
|
+
def visit_text(self, type_: TEXT, **kw):
|
337
|
+
return self.visit_TEXT(type_, **kw)
|
338
|
+
|
339
|
+
def visit_tinytext(self, type_: TINYTEXT, **kw):
|
340
|
+
return self.visit_TINYTEXT(type_, **kw)
|
341
|
+
|
342
|
+
def visit_mediumtext(self, type_: MEDIUMTEXT, **kw):
|
343
|
+
return self.visit_MEDIUMTEXT(type_, **kw)
|
344
|
+
|
345
|
+
def visit_longtext(self, type_: LONGTEXT, **kw):
|
346
|
+
return self.visit_LONGTEXT(type_, **kw)
|
347
|
+
|
348
|
+
def visit_nvarchar(self, type_: NVARCHAR, **kw):
|
349
|
+
return self.visit_NVARCHAR(type_, **kw)
|
350
|
+
|
351
|
+
def visit_nchar(self, type_: NCHAR, **kw):
|
352
|
+
return self.visit_NCHAR(type_, **kw)
|
353
|
+
|
354
|
+
def visit_tinyblob(self, type_: TINYBLOB, **kw):
|
355
|
+
return self.visit_TINYBLOB(type_, **kw)
|
356
|
+
|
357
|
+
def visit_mediumblob(self, type_: MEDIUMBLOB, **kw):
|
358
|
+
return self.visit_MEDIUMBLOB(type_, **kw)
|
359
|
+
|
360
|
+
def visit_longblob(self, type_: LONGBLOB, **kw):
|
361
|
+
return self.visit_LONGBLOB(type_, **kw)
|
362
|
+
|
363
|
+
# endregion
|
364
|
+
|
365
|
+
|
366
|
+
class MySQLDialect(default.DefaultDialect):
|
367
|
+
"""Details of the MySQL dialect.
|
368
|
+
Not used directly in application code.
|
369
|
+
"""
|
370
|
+
|
371
|
+
dbapi: connector
|
372
|
+
name = "mysql"
|
373
|
+
|
374
|
+
statement_compiler = MySQLCompiler
|
375
|
+
ddl_compiler = MySQLDDLCompiler
|
376
|
+
type_compiler_cls = MySQLTypeCompiler
|
377
|
+
repository_cls = MySQLRepository
|
378
|
+
caster = MySQLCaster
|
379
|
+
|
380
|
+
def __init__(self, **kwargs):
|
381
|
+
super().__init__(**kwargs)
|
382
|
+
|
383
|
+
@classmethod
|
384
|
+
def import_dbapi(cls) -> ModuleType:
|
385
|
+
from mysql import connector
|
386
|
+
|
387
|
+
return connector
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# dialects/mysql/mysqlconnector.py
|
2
|
+
# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors
|
3
|
+
# <see AUTHORS file>
|
4
|
+
#
|
5
|
+
# This module is part of SQLAlchemy and is released under
|
6
|
+
# the MIT License: https://www.opensource.org/licenses/mit-license.php
|
7
|
+
# mypy: ignore-errors
|
8
|
+
|
9
|
+
r"""
|
10
|
+
.. dialect:: mysql+mysqlconnector
|
11
|
+
:name: MySQL Connector/Python
|
12
|
+
:dbapi: myconnpy
|
13
|
+
:connectstring: mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname>
|
14
|
+
:url: https://pypi.org/project/mysql-connector-python/
|
15
|
+
|
16
|
+
.. note::
|
17
|
+
|
18
|
+
The MySQL Connector/Python DBAPI has had many issues since its release,
|
19
|
+
some of which may remain unresolved, and the mysqlconnector dialect is
|
20
|
+
The recommended MySQL dialects are mysqlclient and PyMySQL.
|
21
|
+
|
22
|
+
""" # noqa
|
23
|
+
|
24
|
+
from __future__ import annotations
|
25
|
+
from types import ModuleType
|
26
|
+
from .base import MySQLCompiler
|
27
|
+
from .base import MySQLDialect
|
28
|
+
|
29
|
+
|
30
|
+
class MySQLCompiler_mysqlconnector(MySQLCompiler):
|
31
|
+
def visit_mod_binary(self, binary, operator, **kw):
|
32
|
+
return self.process(binary.left, **kw) + " % " + self.process(binary.right, **kw)
|
33
|
+
|
34
|
+
|
35
|
+
class MySQLDialect_mysqlconnector(MySQLDialect):
|
36
|
+
driver = "mysqlconnector"
|
37
|
+
statement_compiler = MySQLCompiler_mysqlconnector
|
38
|
+
|
39
|
+
@classmethod
|
40
|
+
def import_dbapi(cls) -> ModuleType:
|
41
|
+
from mysql import connector
|
42
|
+
|
43
|
+
return connector
|
44
|
+
|
45
|
+
|
46
|
+
dialect = MySQLDialect_mysqlconnector
|