SQLAlchemy 2.0.39__py3-none-any.whl → 2.0.41__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.
- sqlalchemy/__init__.py +1 -12
- sqlalchemy/connectors/pyodbc.py +2 -4
- sqlalchemy/dialects/mssql/base.py +3 -6
- sqlalchemy/dialects/mysql/base.py +15 -9
- sqlalchemy/dialects/mysql/mariadb.py +17 -11
- sqlalchemy/dialects/mysql/mysqlconnector.py +92 -19
- sqlalchemy/dialects/mysql/provision.py +4 -0
- sqlalchemy/dialects/mysql/reflection.py +1 -1
- sqlalchemy/dialects/mysql/types.py +4 -5
- sqlalchemy/dialects/oracle/__init__.py +10 -0
- sqlalchemy/dialects/oracle/base.py +264 -1
- sqlalchemy/dialects/oracle/vector.py +266 -0
- sqlalchemy/dialects/postgresql/_psycopg_common.py +0 -1
- sqlalchemy/dialects/postgresql/array.py +132 -58
- sqlalchemy/dialects/postgresql/base.py +211 -77
- sqlalchemy/dialects/postgresql/ext.py +44 -9
- sqlalchemy/dialects/postgresql/json.py +1 -1
- sqlalchemy/dialects/postgresql/named_types.py +44 -11
- sqlalchemy/dialects/postgresql/pg_catalog.py +19 -7
- sqlalchemy/dialects/sqlite/aiosqlite.py +3 -26
- sqlalchemy/dialects/sqlite/base.py +202 -123
- sqlalchemy/dialects/sqlite/provision.py +0 -2
- sqlalchemy/dialects/sqlite/pysqlite.py +3 -69
- sqlalchemy/engine/base.py +10 -11
- sqlalchemy/engine/cursor.py +6 -1
- sqlalchemy/engine/default.py +28 -15
- sqlalchemy/engine/interfaces.py +11 -4
- sqlalchemy/engine/mock.py +7 -6
- sqlalchemy/engine/reflection.py +4 -1
- sqlalchemy/engine/result.py +10 -3
- sqlalchemy/engine/url.py +1 -1
- sqlalchemy/ext/asyncio/base.py +7 -7
- sqlalchemy/ext/asyncio/engine.py +5 -3
- sqlalchemy/ext/asyncio/scoping.py +1 -2
- sqlalchemy/ext/asyncio/session.py +22 -4
- sqlalchemy/orm/clsregistry.py +2 -2
- sqlalchemy/orm/context.py +1 -3
- sqlalchemy/orm/decl_api.py +1 -1
- sqlalchemy/orm/decl_base.py +1 -3
- sqlalchemy/orm/dependency.py +1 -1
- sqlalchemy/orm/exc.py +9 -0
- sqlalchemy/orm/mapper.py +2 -2
- sqlalchemy/orm/properties.py +12 -5
- sqlalchemy/orm/query.py +5 -6
- sqlalchemy/orm/relationships.py +0 -5
- sqlalchemy/orm/scoping.py +1 -2
- sqlalchemy/orm/session.py +2 -10
- sqlalchemy/orm/strategies.py +0 -3
- sqlalchemy/orm/strategy_options.py +0 -1
- sqlalchemy/orm/util.py +6 -5
- sqlalchemy/pool/base.py +1 -1
- sqlalchemy/schema.py +1 -0
- sqlalchemy/sql/_elements_constructors.py +14 -4
- sqlalchemy/sql/_selectable_constructors.py +2 -0
- sqlalchemy/sql/_typing.py +5 -0
- sqlalchemy/sql/base.py +19 -7
- sqlalchemy/sql/cache_key.py +1 -1
- sqlalchemy/sql/coercions.py +1 -1
- sqlalchemy/sql/compiler.py +238 -132
- sqlalchemy/sql/crud.py +13 -4
- sqlalchemy/sql/ddl.py +51 -47
- sqlalchemy/sql/elements.py +24 -17
- sqlalchemy/sql/functions.py +94 -52
- sqlalchemy/sql/lambdas.py +2 -5
- sqlalchemy/sql/schema.py +26 -9
- sqlalchemy/sql/selectable.py +15 -5
- sqlalchemy/sql/sqltypes.py +119 -42
- sqlalchemy/sql/type_api.py +4 -0
- sqlalchemy/sql/util.py +1 -1
- sqlalchemy/testing/assertions.py +2 -2
- sqlalchemy/testing/fixtures/mypy.py +25 -5
- sqlalchemy/testing/plugin/pytestplugin.py +0 -1
- sqlalchemy/testing/requirements.py +59 -0
- sqlalchemy/testing/suite/test_dialect.py +2 -2
- sqlalchemy/testing/suite/test_reflection.py +49 -3
- sqlalchemy/testing/suite/test_results.py +2 -0
- sqlalchemy/testing/suite/test_select.py +1 -1
- sqlalchemy/util/__init__.py +1 -1
- sqlalchemy/util/_collections.py +3 -1
- sqlalchemy/util/compat.py +2 -0
- sqlalchemy/util/langhelpers.py +112 -31
- sqlalchemy/util/topological.py +1 -1
- sqlalchemy/util/typing.py +71 -27
- {sqlalchemy-2.0.39.dist-info → sqlalchemy-2.0.41.dist-info}/METADATA +10 -10
- {sqlalchemy-2.0.39.dist-info → sqlalchemy-2.0.41.dist-info}/RECORD +88 -87
- {sqlalchemy-2.0.39.dist-info → sqlalchemy-2.0.41.dist-info}/WHEEL +1 -1
- {sqlalchemy-2.0.39.dist-info → sqlalchemy-2.0.41.dist-info/licenses}/LICENSE +0 -0
- {sqlalchemy-2.0.39.dist-info → sqlalchemy-2.0.41.dist-info}/top_level.txt +0 -0
sqlalchemy/__init__.py
CHANGED
|
@@ -269,7 +269,7 @@ from .types import Uuid as Uuid
|
|
|
269
269
|
from .types import VARBINARY as VARBINARY
|
|
270
270
|
from .types import VARCHAR as VARCHAR
|
|
271
271
|
|
|
272
|
-
__version__ = "2.0.
|
|
272
|
+
__version__ = "2.0.41"
|
|
273
273
|
|
|
274
274
|
|
|
275
275
|
def __go(lcls: Any) -> None:
|
|
@@ -281,14 +281,3 @@ def __go(lcls: Any) -> None:
|
|
|
281
281
|
|
|
282
282
|
|
|
283
283
|
__go(locals())
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
def __getattr__(name: str) -> Any:
|
|
287
|
-
if name == "SingleonThreadPool":
|
|
288
|
-
_util.warn_deprecated(
|
|
289
|
-
"SingleonThreadPool was a typo in the v2 series. "
|
|
290
|
-
"Please use the correct SingletonThreadPool name.",
|
|
291
|
-
"2.0.24",
|
|
292
|
-
)
|
|
293
|
-
return SingletonThreadPool
|
|
294
|
-
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
sqlalchemy/connectors/pyodbc.py
CHANGED
|
@@ -227,11 +227,9 @@ class PyODBCConnector(Connector):
|
|
|
227
227
|
)
|
|
228
228
|
|
|
229
229
|
def get_isolation_level_values(
|
|
230
|
-
self,
|
|
230
|
+
self, dbapi_conn: interfaces.DBAPIConnection
|
|
231
231
|
) -> List[IsolationLevel]:
|
|
232
|
-
return super().get_isolation_level_values(
|
|
233
|
-
"AUTOCOMMIT"
|
|
234
|
-
]
|
|
232
|
+
return [*super().get_isolation_level_values(dbapi_conn), "AUTOCOMMIT"]
|
|
235
233
|
|
|
236
234
|
def set_isolation_level(
|
|
237
235
|
self,
|
|
@@ -3991,10 +3991,8 @@ index_info AS (
|
|
|
3991
3991
|
)
|
|
3992
3992
|
|
|
3993
3993
|
# group rows by constraint ID, to handle multi-column FKs
|
|
3994
|
-
fkeys =
|
|
3995
|
-
|
|
3996
|
-
def fkey_rec():
|
|
3997
|
-
return {
|
|
3994
|
+
fkeys = util.defaultdict(
|
|
3995
|
+
lambda: {
|
|
3998
3996
|
"name": None,
|
|
3999
3997
|
"constrained_columns": [],
|
|
4000
3998
|
"referred_schema": None,
|
|
@@ -4002,8 +4000,7 @@ index_info AS (
|
|
|
4002
4000
|
"referred_columns": [],
|
|
4003
4001
|
"options": {},
|
|
4004
4002
|
}
|
|
4005
|
-
|
|
4006
|
-
fkeys = util.defaultdict(fkey_rec)
|
|
4003
|
+
)
|
|
4007
4004
|
|
|
4008
4005
|
for r in connection.execute(s).all():
|
|
4009
4006
|
(
|
|
@@ -1928,12 +1928,13 @@ class MySQLDDLCompiler(compiler.DDLCompiler):
|
|
|
1928
1928
|
colspec.append("AUTO_INCREMENT")
|
|
1929
1929
|
else:
|
|
1930
1930
|
default = self.get_column_default_string(column)
|
|
1931
|
+
|
|
1931
1932
|
if default is not None:
|
|
1932
1933
|
if (
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
)
|
|
1936
|
-
and
|
|
1934
|
+
self.dialect._support_default_function
|
|
1935
|
+
and not re.match(r"^\s*[\'\"\(]", default)
|
|
1936
|
+
and not re.search(r"ON +UPDATE", default, re.I)
|
|
1937
|
+
and re.match(r".*\W.*", default)
|
|
1937
1938
|
):
|
|
1938
1939
|
colspec.append(f"DEFAULT ({default})")
|
|
1939
1940
|
else:
|
|
@@ -2520,6 +2521,10 @@ class MySQLDialect(default.DefaultDialect):
|
|
|
2520
2521
|
# allow for the "true" and "false" keywords, however
|
|
2521
2522
|
supports_native_boolean = False
|
|
2522
2523
|
|
|
2524
|
+
# support for BIT type; mysqlconnector coerces result values automatically,
|
|
2525
|
+
# all other MySQL DBAPIs require a conversion routine
|
|
2526
|
+
supports_native_bit = False
|
|
2527
|
+
|
|
2523
2528
|
# identifiers are 64, however aliases can be 255...
|
|
2524
2529
|
max_identifier_length = 255
|
|
2525
2530
|
max_index_name_length = 64
|
|
@@ -2721,10 +2726,12 @@ class MySQLDialect(default.DefaultDialect):
|
|
|
2721
2726
|
% (".".join(map(str, server_version_info)),)
|
|
2722
2727
|
)
|
|
2723
2728
|
if is_mariadb:
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2729
|
+
|
|
2730
|
+
if not issubclass(self.preparer, MariaDBIdentifierPreparer):
|
|
2731
|
+
self.preparer = MariaDBIdentifierPreparer
|
|
2732
|
+
# this would have been set by the default dialect already,
|
|
2733
|
+
# so set it again
|
|
2734
|
+
self.identifier_preparer = self.preparer(self)
|
|
2728
2735
|
|
|
2729
2736
|
# this will be updated on first connect in initialize()
|
|
2730
2737
|
# if using older mariadb version
|
|
@@ -3471,7 +3478,6 @@ class MySQLDialect(default.DefaultDialect):
|
|
|
3471
3478
|
full_name = self.identifier_preparer.format_table(table)
|
|
3472
3479
|
st = "SHOW CREATE TABLE %s" % full_name
|
|
3473
3480
|
|
|
3474
|
-
rp = None
|
|
3475
3481
|
try:
|
|
3476
3482
|
rp = connection.execution_options(
|
|
3477
3483
|
skip_user_error_events=True
|
|
@@ -46,16 +46,22 @@ class MariaDBDialect(MySQLDialect):
|
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
def loader(driver):
|
|
49
|
-
|
|
49
|
+
dialect_mod = __import__(
|
|
50
50
|
"sqlalchemy.dialects.mysql.%s" % driver
|
|
51
51
|
).dialects.mysql
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
|
|
53
|
+
driver_mod = getattr(dialect_mod, driver)
|
|
54
|
+
if hasattr(driver_mod, "mariadb_dialect"):
|
|
55
|
+
driver_cls = driver_mod.mariadb_dialect
|
|
56
|
+
return driver_cls
|
|
57
|
+
else:
|
|
58
|
+
driver_cls = driver_mod.dialect
|
|
59
|
+
|
|
60
|
+
return type(
|
|
61
|
+
"MariaDBDialect_%s" % driver,
|
|
62
|
+
(
|
|
63
|
+
MariaDBDialect,
|
|
64
|
+
driver_cls,
|
|
65
|
+
),
|
|
66
|
+
{"supports_statement_cache": True},
|
|
67
|
+
)
|
|
@@ -14,24 +14,59 @@ r"""
|
|
|
14
14
|
:connectstring: mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname>
|
|
15
15
|
:url: https://pypi.org/project/mysql-connector-python/
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Driver Status
|
|
18
|
+
-------------
|
|
19
|
+
|
|
20
|
+
MySQL Connector/Python is supported as of SQLAlchemy 2.0.39 to the
|
|
21
|
+
degree which the driver is functional. There are still ongoing issues
|
|
22
|
+
with features such as server side cursors which remain disabled until
|
|
23
|
+
upstream issues are repaired.
|
|
24
|
+
|
|
25
|
+
.. warning:: The MySQL Connector/Python driver published by Oracle is subject
|
|
26
|
+
to frequent, major regressions of essential functionality such as being able
|
|
27
|
+
to correctly persist simple binary strings which indicate it is not well
|
|
28
|
+
tested. The SQLAlchemy project is not able to maintain this dialect fully as
|
|
29
|
+
regressions in the driver prevent it from being included in continuous
|
|
30
|
+
integration.
|
|
31
|
+
|
|
32
|
+
.. versionchanged:: 2.0.39
|
|
33
|
+
|
|
34
|
+
The MySQL Connector/Python dialect has been updated to support the
|
|
35
|
+
latest version of this DBAPI. Previously, MySQL Connector/Python
|
|
36
|
+
was not fully supported. However, support remains limited due to ongoing
|
|
37
|
+
regressions introduced in this driver.
|
|
38
|
+
|
|
39
|
+
Connecting to MariaDB with MySQL Connector/Python
|
|
40
|
+
--------------------------------------------------
|
|
41
|
+
|
|
42
|
+
MySQL Connector/Python may attempt to pass an incompatible collation to the
|
|
43
|
+
database when connecting to MariaDB. Experimentation has shown that using
|
|
44
|
+
``?charset=utf8mb4&collation=utfmb4_general_ci`` or similar MariaDB-compatible
|
|
45
|
+
charset/collation will allow connectivity.
|
|
18
46
|
|
|
19
|
-
The MySQL Connector/Python DBAPI has had many issues since its release,
|
|
20
|
-
some of which may remain unresolved, and the mysqlconnector dialect is
|
|
21
|
-
**not tested as part of SQLAlchemy's continuous integration**.
|
|
22
|
-
The recommended MySQL dialects are mysqlclient and PyMySQL.
|
|
23
47
|
|
|
24
48
|
""" # noqa
|
|
25
49
|
|
|
26
50
|
import re
|
|
27
51
|
|
|
28
52
|
from .base import BIT
|
|
53
|
+
from .base import MariaDBIdentifierPreparer
|
|
29
54
|
from .base import MySQLCompiler
|
|
30
55
|
from .base import MySQLDialect
|
|
56
|
+
from .base import MySQLExecutionContext
|
|
31
57
|
from .base import MySQLIdentifierPreparer
|
|
58
|
+
from .mariadb import MariaDBDialect
|
|
32
59
|
from ... import util
|
|
33
60
|
|
|
34
61
|
|
|
62
|
+
class MySQLExecutionContext_mysqlconnector(MySQLExecutionContext):
|
|
63
|
+
def create_server_side_cursor(self):
|
|
64
|
+
return self._dbapi_connection.cursor(buffered=False)
|
|
65
|
+
|
|
66
|
+
def create_default_cursor(self):
|
|
67
|
+
return self._dbapi_connection.cursor(buffered=True)
|
|
68
|
+
|
|
69
|
+
|
|
35
70
|
class MySQLCompiler_mysqlconnector(MySQLCompiler):
|
|
36
71
|
def visit_mod_binary(self, binary, operator, **kw):
|
|
37
72
|
return (
|
|
@@ -41,7 +76,7 @@ class MySQLCompiler_mysqlconnector(MySQLCompiler):
|
|
|
41
76
|
)
|
|
42
77
|
|
|
43
78
|
|
|
44
|
-
class
|
|
79
|
+
class IdentifierPreparerCommon_mysqlconnector:
|
|
45
80
|
@property
|
|
46
81
|
def _double_percents(self):
|
|
47
82
|
return False
|
|
@@ -55,6 +90,18 @@ class MySQLIdentifierPreparer_mysqlconnector(MySQLIdentifierPreparer):
|
|
|
55
90
|
return value
|
|
56
91
|
|
|
57
92
|
|
|
93
|
+
class MySQLIdentifierPreparer_mysqlconnector(
|
|
94
|
+
IdentifierPreparerCommon_mysqlconnector, MySQLIdentifierPreparer
|
|
95
|
+
):
|
|
96
|
+
pass
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class MariaDBIdentifierPreparer_mysqlconnector(
|
|
100
|
+
IdentifierPreparerCommon_mysqlconnector, MariaDBIdentifierPreparer
|
|
101
|
+
):
|
|
102
|
+
pass
|
|
103
|
+
|
|
104
|
+
|
|
58
105
|
class _myconnpyBIT(BIT):
|
|
59
106
|
def result_processor(self, dialect, coltype):
|
|
60
107
|
"""MySQL-connector already converts mysql bits, so."""
|
|
@@ -71,9 +118,16 @@ class MySQLDialect_mysqlconnector(MySQLDialect):
|
|
|
71
118
|
|
|
72
119
|
supports_native_decimal = True
|
|
73
120
|
|
|
121
|
+
supports_native_bit = True
|
|
122
|
+
|
|
123
|
+
# not until https://bugs.mysql.com/bug.php?id=117548
|
|
124
|
+
supports_server_side_cursors = False
|
|
125
|
+
|
|
74
126
|
default_paramstyle = "format"
|
|
75
127
|
statement_compiler = MySQLCompiler_mysqlconnector
|
|
76
128
|
|
|
129
|
+
execution_ctx_cls = MySQLExecutionContext_mysqlconnector
|
|
130
|
+
|
|
77
131
|
preparer = MySQLIdentifierPreparer_mysqlconnector
|
|
78
132
|
|
|
79
133
|
colspecs = util.update_copy(MySQLDialect.colspecs, {BIT: _myconnpyBIT})
|
|
@@ -111,9 +165,13 @@ class MySQLDialect_mysqlconnector(MySQLDialect):
|
|
|
111
165
|
util.coerce_kw_type(opts, "use_pure", bool)
|
|
112
166
|
util.coerce_kw_type(opts, "use_unicode", bool)
|
|
113
167
|
|
|
114
|
-
#
|
|
115
|
-
#
|
|
116
|
-
|
|
168
|
+
# note that "buffered" is set to False by default in MySQL/connector
|
|
169
|
+
# python. If you set it to True, then there is no way to get a server
|
|
170
|
+
# side cursor because the logic is written to disallow that.
|
|
171
|
+
|
|
172
|
+
# leaving this at True until
|
|
173
|
+
# https://bugs.mysql.com/bug.php?id=117548 can be fixed
|
|
174
|
+
opts["buffered"] = True
|
|
117
175
|
|
|
118
176
|
# FOUND_ROWS must be set in ClientFlag to enable
|
|
119
177
|
# supports_sane_rowcount.
|
|
@@ -128,6 +186,7 @@ class MySQLDialect_mysqlconnector(MySQLDialect):
|
|
|
128
186
|
opts["client_flags"] = client_flags
|
|
129
187
|
except Exception:
|
|
130
188
|
pass
|
|
189
|
+
|
|
131
190
|
return [[], opts]
|
|
132
191
|
|
|
133
192
|
@util.memoized_property
|
|
@@ -145,7 +204,11 @@ class MySQLDialect_mysqlconnector(MySQLDialect):
|
|
|
145
204
|
|
|
146
205
|
def is_disconnect(self, e, connection, cursor):
|
|
147
206
|
errnos = (2006, 2013, 2014, 2045, 2055, 2048)
|
|
148
|
-
exceptions = (
|
|
207
|
+
exceptions = (
|
|
208
|
+
self.dbapi.OperationalError,
|
|
209
|
+
self.dbapi.InterfaceError,
|
|
210
|
+
self.dbapi.ProgrammingError,
|
|
211
|
+
)
|
|
149
212
|
if isinstance(e, exceptions):
|
|
150
213
|
return (
|
|
151
214
|
e.errno in errnos
|
|
@@ -161,20 +224,30 @@ class MySQLDialect_mysqlconnector(MySQLDialect):
|
|
|
161
224
|
def _compat_fetchone(self, rp, charset=None):
|
|
162
225
|
return rp.fetchone()
|
|
163
226
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
227
|
+
def get_isolation_level_values(self, dbapi_connection):
|
|
228
|
+
return (
|
|
229
|
+
"SERIALIZABLE",
|
|
230
|
+
"READ UNCOMMITTED",
|
|
231
|
+
"READ COMMITTED",
|
|
232
|
+
"REPEATABLE READ",
|
|
233
|
+
"AUTOCOMMIT",
|
|
234
|
+
)
|
|
171
235
|
|
|
172
|
-
def
|
|
236
|
+
def set_isolation_level(self, connection, level):
|
|
173
237
|
if level == "AUTOCOMMIT":
|
|
174
238
|
connection.autocommit = True
|
|
175
239
|
else:
|
|
176
240
|
connection.autocommit = False
|
|
177
|
-
super().
|
|
241
|
+
super().set_isolation_level(connection, level)
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
class MariaDBDialect_mysqlconnector(
|
|
245
|
+
MariaDBDialect, MySQLDialect_mysqlconnector
|
|
246
|
+
):
|
|
247
|
+
supports_statement_cache = True
|
|
248
|
+
_allows_uuid_binds = False
|
|
249
|
+
preparer = MariaDBIdentifierPreparer_mysqlconnector
|
|
178
250
|
|
|
179
251
|
|
|
180
252
|
dialect = MySQLDialect_mysqlconnector
|
|
253
|
+
mariadb_dialect = MariaDBDialect_mysqlconnector
|
|
@@ -42,6 +42,10 @@ def generate_driver_url(url, driver, query_str):
|
|
|
42
42
|
|
|
43
43
|
if driver == "mariadbconnector":
|
|
44
44
|
new_url = new_url.difference_update_query(["charset"])
|
|
45
|
+
elif driver == "mysqlconnector":
|
|
46
|
+
new_url = new_url.update_query_pairs(
|
|
47
|
+
[("collation", "utf8mb4_general_ci")]
|
|
48
|
+
)
|
|
45
49
|
|
|
46
50
|
try:
|
|
47
51
|
new_url.get_dialect()
|
|
@@ -451,7 +451,7 @@ class MySQLTableDefinitionParser:
|
|
|
451
451
|
r"(?: +COLLATE +(?P<collate>[\w_]+))?"
|
|
452
452
|
r"(?: +(?P<notnull>(?:NOT )?NULL))?"
|
|
453
453
|
r"(?: +DEFAULT +(?P<default>"
|
|
454
|
-
r"(?:NULL|'(?:''|[^'])*'|[\-\w\.\(\)]+"
|
|
454
|
+
r"(?:NULL|'(?:''|[^'])*'|\(.+?\)|[\-\w\.\(\)]+"
|
|
455
455
|
r"(?: +ON UPDATE [\-\w\.\(\)]+)?)"
|
|
456
456
|
r"))?"
|
|
457
457
|
r"(?: +(?:GENERATED ALWAYS)? ?AS +(?P<generated>\("
|
|
@@ -374,12 +374,11 @@ class BIT(sqltypes.TypeEngine):
|
|
|
374
374
|
self.length = length
|
|
375
375
|
|
|
376
376
|
def result_processor(self, dialect, coltype):
|
|
377
|
-
"""Convert a MySQL's 64 bit, variable length binary string to a
|
|
377
|
+
"""Convert a MySQL's 64 bit, variable length binary string to a
|
|
378
|
+
long."""
|
|
378
379
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
"""
|
|
380
|
+
if dialect.supports_native_bit:
|
|
381
|
+
return None
|
|
383
382
|
|
|
384
383
|
def process(value):
|
|
385
384
|
if value is not None:
|
|
@@ -32,6 +32,11 @@ from .base import ROWID
|
|
|
32
32
|
from .base import TIMESTAMP
|
|
33
33
|
from .base import VARCHAR
|
|
34
34
|
from .base import VARCHAR2
|
|
35
|
+
from .base import VECTOR
|
|
36
|
+
from .base import VectorIndexConfig
|
|
37
|
+
from .base import VectorIndexType
|
|
38
|
+
from .vector import VectorDistanceType
|
|
39
|
+
from .vector import VectorStorageFormat
|
|
35
40
|
|
|
36
41
|
# Alias oracledb also as oracledb_async
|
|
37
42
|
oracledb_async = type(
|
|
@@ -64,4 +69,9 @@ __all__ = (
|
|
|
64
69
|
"NVARCHAR2",
|
|
65
70
|
"ROWID",
|
|
66
71
|
"REAL",
|
|
72
|
+
"VECTOR",
|
|
73
|
+
"VectorDistanceType",
|
|
74
|
+
"VectorIndexType",
|
|
75
|
+
"VectorIndexConfig",
|
|
76
|
+
"VectorStorageFormat",
|
|
67
77
|
)
|