SQLAlchemy 2.0.40__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/dialects/mssql/base.py +3 -6
- sqlalchemy/dialects/mysql/base.py +1 -2
- sqlalchemy/dialects/mysql/mysqlconnector.py +9 -1
- 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/base.py +167 -74
- sqlalchemy/dialects/postgresql/ext.py +44 -9
- 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 +187 -119
- sqlalchemy/dialects/sqlite/provision.py +0 -2
- sqlalchemy/dialects/sqlite/pysqlite.py +3 -69
- sqlalchemy/engine/base.py +10 -11
- sqlalchemy/engine/default.py +1 -3
- 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/scoping.py +1 -2
- sqlalchemy/ext/asyncio/session.py +1 -2
- sqlalchemy/orm/clsregistry.py +2 -2
- sqlalchemy/orm/context.py +1 -3
- sqlalchemy/orm/decl_base.py +0 -2
- sqlalchemy/orm/dependency.py +1 -1
- sqlalchemy/orm/mapper.py +2 -2
- sqlalchemy/orm/properties.py +0 -2
- 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/schema.py +1 -0
- sqlalchemy/sql/_typing.py +5 -0
- sqlalchemy/sql/base.py +19 -7
- sqlalchemy/sql/cache_key.py +1 -1
- sqlalchemy/sql/compiler.py +1 -1
- sqlalchemy/sql/crud.py +1 -1
- sqlalchemy/sql/ddl.py +2 -1
- sqlalchemy/sql/functions.py +57 -50
- sqlalchemy/sql/lambdas.py +2 -5
- sqlalchemy/sql/schema.py +3 -4
- sqlalchemy/sql/selectable.py +15 -5
- sqlalchemy/sql/sqltypes.py +21 -8
- sqlalchemy/testing/fixtures/mypy.py +25 -5
- sqlalchemy/testing/plugin/pytestplugin.py +0 -1
- sqlalchemy/testing/requirements.py +46 -0
- sqlalchemy/testing/suite/test_dialect.py +2 -2
- sqlalchemy/testing/suite/test_reflection.py +5 -3
- sqlalchemy/testing/suite/test_select.py +1 -1
- sqlalchemy/util/__init__.py +1 -1
- sqlalchemy/util/compat.py +2 -0
- sqlalchemy/util/langhelpers.py +112 -31
- sqlalchemy/util/topological.py +1 -1
- sqlalchemy/util/typing.py +8 -7
- {sqlalchemy-2.0.40.dist-info → sqlalchemy-2.0.41.dist-info}/METADATA +1 -2
- {sqlalchemy-2.0.40.dist-info → sqlalchemy-2.0.41.dist-info}/RECORD +64 -63
- {sqlalchemy-2.0.40.dist-info → sqlalchemy-2.0.41.dist-info}/WHEEL +1 -1
- {sqlalchemy-2.0.40.dist-info → sqlalchemy-2.0.41.dist-info}/licenses/LICENSE +0 -0
- {sqlalchemy-2.0.40.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}")
|
|
@@ -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
|
(
|
|
@@ -1933,7 +1933,7 @@ class MySQLDDLCompiler(compiler.DDLCompiler):
|
|
|
1933
1933
|
if (
|
|
1934
1934
|
self.dialect._support_default_function
|
|
1935
1935
|
and not re.match(r"^\s*[\'\"\(]", default)
|
|
1936
|
-
and "ON UPDATE"
|
|
1936
|
+
and not re.search(r"ON +UPDATE", default, re.I)
|
|
1937
1937
|
and re.match(r".*\W.*", default)
|
|
1938
1938
|
):
|
|
1939
1939
|
colspec.append(f"DEFAULT ({default})")
|
|
@@ -3478,7 +3478,6 @@ class MySQLDialect(default.DefaultDialect):
|
|
|
3478
3478
|
full_name = self.identifier_preparer.format_table(table)
|
|
3479
3479
|
st = "SHOW CREATE TABLE %s" % full_name
|
|
3480
3480
|
|
|
3481
|
-
rp = None
|
|
3482
3481
|
try:
|
|
3483
3482
|
rp = connection.execution_options(
|
|
3484
3483
|
skip_user_error_events=True
|
|
@@ -22,11 +22,19 @@ degree which the driver is functional. There are still ongoing issues
|
|
|
22
22
|
with features such as server side cursors which remain disabled until
|
|
23
23
|
upstream issues are repaired.
|
|
24
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
|
+
|
|
25
32
|
.. versionchanged:: 2.0.39
|
|
26
33
|
|
|
27
34
|
The MySQL Connector/Python dialect has been updated to support the
|
|
28
35
|
latest version of this DBAPI. Previously, MySQL Connector/Python
|
|
29
|
-
was not fully supported.
|
|
36
|
+
was not fully supported. However, support remains limited due to ongoing
|
|
37
|
+
regressions introduced in this driver.
|
|
30
38
|
|
|
31
39
|
Connecting to MariaDB with MySQL Connector/Python
|
|
32
40
|
--------------------------------------------------
|
|
@@ -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
|
)
|
|
@@ -722,11 +722,177 @@ The ``oracle_compress`` parameter accepts either an integer specifying the
|
|
|
722
722
|
number of prefix columns to compress, or ``True`` to use the default (all
|
|
723
723
|
columns for non-unique indexes, all but the last column for unique indexes).
|
|
724
724
|
|
|
725
|
+
.. _oracle_vector_datatype:
|
|
726
|
+
|
|
727
|
+
VECTOR Datatype
|
|
728
|
+
---------------
|
|
729
|
+
|
|
730
|
+
Oracle Database 23ai introduced a new VECTOR datatype for artificial intelligence
|
|
731
|
+
and machine learning search operations. The VECTOR datatype is a homogeneous array
|
|
732
|
+
of 8-bit signed integers, 8-bit unsigned integers (binary), 32-bit floating-point numbers,
|
|
733
|
+
or 64-bit floating-point numbers.
|
|
734
|
+
|
|
735
|
+
.. seealso::
|
|
736
|
+
|
|
737
|
+
`Using VECTOR Data
|
|
738
|
+
<https://python-oracledb.readthedocs.io/en/latest/user_guide/vector_data_type.html>`_ - in the documentation
|
|
739
|
+
for the :ref:`oracledb` driver.
|
|
740
|
+
|
|
741
|
+
.. versionadded:: 2.0.41
|
|
742
|
+
|
|
743
|
+
CREATE TABLE support for VECTOR
|
|
744
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
745
|
+
|
|
746
|
+
With the :class:`.VECTOR` datatype, you can specify the dimension for the data
|
|
747
|
+
and the storage format. Valid values for storage format are enum values from
|
|
748
|
+
:class:`.VectorStorageFormat`. To create a table that includes a
|
|
749
|
+
:class:`.VECTOR` column::
|
|
750
|
+
|
|
751
|
+
from sqlalchemy.dialects.oracle import VECTOR, VectorStorageFormat
|
|
752
|
+
|
|
753
|
+
t = Table(
|
|
754
|
+
"t1",
|
|
755
|
+
metadata,
|
|
756
|
+
Column("id", Integer, primary_key=True),
|
|
757
|
+
Column(
|
|
758
|
+
"embedding",
|
|
759
|
+
VECTOR(dim=3, storage_format=VectorStorageFormat.FLOAT32),
|
|
760
|
+
),
|
|
761
|
+
Column(...),
|
|
762
|
+
...,
|
|
763
|
+
)
|
|
764
|
+
|
|
765
|
+
Vectors can also be defined with an arbitrary number of dimensions and formats.
|
|
766
|
+
This allows you to specify vectors of different dimensions with the various
|
|
767
|
+
storage formats mentioned above.
|
|
768
|
+
|
|
769
|
+
**Examples**
|
|
770
|
+
|
|
771
|
+
* In this case, the storage format is flexible, allowing any vector type data to be inserted,
|
|
772
|
+
such as INT8 or BINARY etc::
|
|
773
|
+
|
|
774
|
+
vector_col: Mapped[array.array] = mapped_column(VECTOR(dim=3))
|
|
775
|
+
|
|
776
|
+
* The dimension is flexible in this case, meaning that any dimension vector can be used::
|
|
777
|
+
|
|
778
|
+
vector_col: Mapped[array.array] = mapped_column(
|
|
779
|
+
VECTOR(storage_format=VectorStorageType.INT8)
|
|
780
|
+
)
|
|
781
|
+
|
|
782
|
+
* Both the dimensions and the storage format are flexible::
|
|
783
|
+
|
|
784
|
+
vector_col: Mapped[array.array] = mapped_column(VECTOR)
|
|
785
|
+
|
|
786
|
+
Python Datatypes for VECTOR
|
|
787
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
788
|
+
|
|
789
|
+
VECTOR data can be inserted using Python list or Python ``array.array()`` objects.
|
|
790
|
+
Python arrays of type FLOAT (32-bit), DOUBLE (64-bit), or INT (8-bit signed integer)
|
|
791
|
+
are used as bind values when inserting VECTOR columns::
|
|
792
|
+
|
|
793
|
+
from sqlalchemy import insert, select
|
|
794
|
+
|
|
795
|
+
with engine.begin() as conn:
|
|
796
|
+
conn.execute(
|
|
797
|
+
insert(t1),
|
|
798
|
+
{"id": 1, "embedding": [1, 2, 3]},
|
|
799
|
+
)
|
|
800
|
+
|
|
801
|
+
VECTOR Indexes
|
|
802
|
+
~~~~~~~~~~~~~~
|
|
803
|
+
|
|
804
|
+
The VECTOR feature supports an Oracle-specific parameter ``oracle_vector``
|
|
805
|
+
on the :class:`.Index` construct, which allows the construction of VECTOR
|
|
806
|
+
indexes.
|
|
807
|
+
|
|
808
|
+
To utilize VECTOR indexing, set the ``oracle_vector`` parameter to True to use
|
|
809
|
+
the default values provided by Oracle. HNSW is the default indexing method::
|
|
810
|
+
|
|
811
|
+
from sqlalchemy import Index
|
|
812
|
+
|
|
813
|
+
Index(
|
|
814
|
+
"vector_index",
|
|
815
|
+
t1.c.embedding,
|
|
816
|
+
oracle_vector=True,
|
|
817
|
+
)
|
|
818
|
+
|
|
819
|
+
The full range of parameters for vector indexes are available by using the
|
|
820
|
+
:class:`.VectorIndexConfig` dataclass in place of a boolean; this dataclass
|
|
821
|
+
allows full configuration of the index::
|
|
822
|
+
|
|
823
|
+
Index(
|
|
824
|
+
"hnsw_vector_index",
|
|
825
|
+
t1.c.embedding,
|
|
826
|
+
oracle_vector=VectorIndexConfig(
|
|
827
|
+
index_type=VectorIndexType.HNSW,
|
|
828
|
+
distance=VectorDistanceType.COSINE,
|
|
829
|
+
accuracy=90,
|
|
830
|
+
hnsw_neighbors=5,
|
|
831
|
+
hnsw_efconstruction=20,
|
|
832
|
+
parallel=10,
|
|
833
|
+
),
|
|
834
|
+
)
|
|
835
|
+
|
|
836
|
+
Index(
|
|
837
|
+
"ivf_vector_index",
|
|
838
|
+
t1.c.embedding,
|
|
839
|
+
oracle_vector=VectorIndexConfig(
|
|
840
|
+
index_type=VectorIndexType.IVF,
|
|
841
|
+
distance=VectorDistanceType.DOT,
|
|
842
|
+
accuracy=90,
|
|
843
|
+
ivf_neighbor_partitions=5,
|
|
844
|
+
),
|
|
845
|
+
)
|
|
846
|
+
|
|
847
|
+
For complete explanation of these parameters, see the Oracle documentation linked
|
|
848
|
+
below.
|
|
849
|
+
|
|
850
|
+
.. seealso::
|
|
851
|
+
|
|
852
|
+
`CREATE VECTOR INDEX <https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-B396C369-54BB-4098-A0DD-7C54B3A0D66F>`_ - in the Oracle documentation
|
|
853
|
+
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
Similarity Searching
|
|
857
|
+
~~~~~~~~~~~~~~~~~~~~
|
|
858
|
+
|
|
859
|
+
When using the :class:`_oracle.VECTOR` datatype with a :class:`.Column` or similar
|
|
860
|
+
ORM mapped construct, additional comparison functions are available, including:
|
|
861
|
+
|
|
862
|
+
* ``l2_distance``
|
|
863
|
+
* ``cosine_distance``
|
|
864
|
+
* ``inner_product``
|
|
865
|
+
|
|
866
|
+
Example Usage::
|
|
867
|
+
|
|
868
|
+
result_vector = connection.scalars(
|
|
869
|
+
select(t1).order_by(t1.embedding.l2_distance([2, 3, 4])).limit(3)
|
|
870
|
+
)
|
|
871
|
+
|
|
872
|
+
for user in vector:
|
|
873
|
+
print(user.id, user.embedding)
|
|
874
|
+
|
|
875
|
+
FETCH APPROXIMATE support
|
|
876
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
877
|
+
|
|
878
|
+
Approximate vector search can only be performed when all syntax and semantic
|
|
879
|
+
rules are satisfied, the corresponding vector index is available, and the
|
|
880
|
+
query optimizer determines to perform it. If any of these conditions are
|
|
881
|
+
unmet, then an approximate search is not performed. In this case the query
|
|
882
|
+
returns exact results.
|
|
883
|
+
|
|
884
|
+
To enable approximate searching during similarity searches on VECTORS, the
|
|
885
|
+
``oracle_fetch_approximate`` parameter may be used with the :meth:`.Select.fetch`
|
|
886
|
+
clause to add ``FETCH APPROX`` to the SELECT statement::
|
|
887
|
+
|
|
888
|
+
select(users_table).fetch(5, oracle_fetch_approximate=True)
|
|
889
|
+
|
|
725
890
|
""" # noqa
|
|
726
891
|
|
|
727
892
|
from __future__ import annotations
|
|
728
893
|
|
|
729
894
|
from collections import defaultdict
|
|
895
|
+
from dataclasses import fields
|
|
730
896
|
from functools import lru_cache
|
|
731
897
|
from functools import wraps
|
|
732
898
|
import re
|
|
@@ -749,6 +915,9 @@ from .types import RAW
|
|
|
749
915
|
from .types import ROWID # noqa
|
|
750
916
|
from .types import TIMESTAMP
|
|
751
917
|
from .types import VARCHAR2 # noqa
|
|
918
|
+
from .vector import VECTOR
|
|
919
|
+
from .vector import VectorIndexConfig
|
|
920
|
+
from .vector import VectorIndexType
|
|
752
921
|
from ... import Computed
|
|
753
922
|
from ... import exc
|
|
754
923
|
from ... import schema as sa_schema
|
|
@@ -767,6 +936,7 @@ from ...sql import func
|
|
|
767
936
|
from ...sql import null
|
|
768
937
|
from ...sql import or_
|
|
769
938
|
from ...sql import select
|
|
939
|
+
from ...sql import selectable as sa_selectable
|
|
770
940
|
from ...sql import sqltypes
|
|
771
941
|
from ...sql import util as sql_util
|
|
772
942
|
from ...sql import visitors
|
|
@@ -828,6 +998,7 @@ ischema_names = {
|
|
|
828
998
|
"BINARY_DOUBLE": BINARY_DOUBLE,
|
|
829
999
|
"BINARY_FLOAT": BINARY_FLOAT,
|
|
830
1000
|
"ROWID": ROWID,
|
|
1001
|
+
"VECTOR": VECTOR,
|
|
831
1002
|
}
|
|
832
1003
|
|
|
833
1004
|
|
|
@@ -985,6 +1156,16 @@ class OracleTypeCompiler(compiler.GenericTypeCompiler):
|
|
|
985
1156
|
def visit_ROWID(self, type_, **kw):
|
|
986
1157
|
return "ROWID"
|
|
987
1158
|
|
|
1159
|
+
def visit_VECTOR(self, type_, **kw):
|
|
1160
|
+
if type_.dim is None and type_.storage_format is None:
|
|
1161
|
+
return "VECTOR(*,*)"
|
|
1162
|
+
elif type_.storage_format is None:
|
|
1163
|
+
return f"VECTOR({type_.dim},*)"
|
|
1164
|
+
elif type_.dim is None:
|
|
1165
|
+
return f"VECTOR(*,{type_.storage_format.value})"
|
|
1166
|
+
else:
|
|
1167
|
+
return f"VECTOR({type_.dim},{type_.storage_format.value})"
|
|
1168
|
+
|
|
988
1169
|
|
|
989
1170
|
class OracleCompiler(compiler.SQLCompiler):
|
|
990
1171
|
"""Oracle compiler modifies the lexical structure of Select
|
|
@@ -1223,6 +1404,29 @@ class OracleCompiler(compiler.SQLCompiler):
|
|
|
1223
1404
|
else:
|
|
1224
1405
|
return select._fetch_clause
|
|
1225
1406
|
|
|
1407
|
+
def fetch_clause(
|
|
1408
|
+
self,
|
|
1409
|
+
select,
|
|
1410
|
+
fetch_clause=None,
|
|
1411
|
+
require_offset=False,
|
|
1412
|
+
use_literal_execute_for_simple_int=False,
|
|
1413
|
+
**kw,
|
|
1414
|
+
):
|
|
1415
|
+
text = super().fetch_clause(
|
|
1416
|
+
select,
|
|
1417
|
+
fetch_clause=fetch_clause,
|
|
1418
|
+
require_offset=require_offset,
|
|
1419
|
+
use_literal_execute_for_simple_int=(
|
|
1420
|
+
use_literal_execute_for_simple_int
|
|
1421
|
+
),
|
|
1422
|
+
**kw,
|
|
1423
|
+
)
|
|
1424
|
+
|
|
1425
|
+
if select.dialect_options["oracle"]["fetch_approximate"]:
|
|
1426
|
+
text = re.sub("FETCH FIRST", "FETCH APPROX FIRST", text)
|
|
1427
|
+
|
|
1428
|
+
return text
|
|
1429
|
+
|
|
1226
1430
|
def translate_select_structure(self, select_stmt, **kwargs):
|
|
1227
1431
|
select = select_stmt
|
|
1228
1432
|
|
|
@@ -1471,6 +1675,48 @@ class OracleCompiler(compiler.SQLCompiler):
|
|
|
1471
1675
|
|
|
1472
1676
|
|
|
1473
1677
|
class OracleDDLCompiler(compiler.DDLCompiler):
|
|
1678
|
+
|
|
1679
|
+
def _build_vector_index_config(
|
|
1680
|
+
self, vector_index_config: VectorIndexConfig
|
|
1681
|
+
) -> str:
|
|
1682
|
+
parts = []
|
|
1683
|
+
sql_param_name = {
|
|
1684
|
+
"hnsw_neighbors": "neighbors",
|
|
1685
|
+
"hnsw_efconstruction": "efconstruction",
|
|
1686
|
+
"ivf_neighbor_partitions": "neighbor partitions",
|
|
1687
|
+
"ivf_sample_per_partition": "sample_per_partition",
|
|
1688
|
+
"ivf_min_vectors_per_partition": "min_vectors_per_partition",
|
|
1689
|
+
}
|
|
1690
|
+
if vector_index_config.index_type == VectorIndexType.HNSW:
|
|
1691
|
+
parts.append("ORGANIZATION INMEMORY NEIGHBOR GRAPH")
|
|
1692
|
+
elif vector_index_config.index_type == VectorIndexType.IVF:
|
|
1693
|
+
parts.append("ORGANIZATION NEIGHBOR PARTITIONS")
|
|
1694
|
+
if vector_index_config.distance is not None:
|
|
1695
|
+
parts.append(f"DISTANCE {vector_index_config.distance.value}")
|
|
1696
|
+
|
|
1697
|
+
if vector_index_config.accuracy is not None:
|
|
1698
|
+
parts.append(
|
|
1699
|
+
f"WITH TARGET ACCURACY {vector_index_config.accuracy}"
|
|
1700
|
+
)
|
|
1701
|
+
|
|
1702
|
+
parameters_str = [f"type {vector_index_config.index_type.name}"]
|
|
1703
|
+
prefix = vector_index_config.index_type.name.lower() + "_"
|
|
1704
|
+
|
|
1705
|
+
for field in fields(vector_index_config):
|
|
1706
|
+
if field.name.startswith(prefix):
|
|
1707
|
+
key = sql_param_name.get(field.name)
|
|
1708
|
+
value = getattr(vector_index_config, field.name)
|
|
1709
|
+
if value is not None:
|
|
1710
|
+
parameters_str.append(f"{key} {value}")
|
|
1711
|
+
|
|
1712
|
+
parameters_str = ", ".join(parameters_str)
|
|
1713
|
+
parts.append(f"PARAMETERS ({parameters_str})")
|
|
1714
|
+
|
|
1715
|
+
if vector_index_config.parallel is not None:
|
|
1716
|
+
parts.append(f"PARALLEL {vector_index_config.parallel}")
|
|
1717
|
+
|
|
1718
|
+
return " ".join(parts)
|
|
1719
|
+
|
|
1474
1720
|
def define_constraint_cascades(self, constraint):
|
|
1475
1721
|
text = ""
|
|
1476
1722
|
if constraint.ondelete is not None:
|
|
@@ -1503,6 +1749,9 @@ class OracleDDLCompiler(compiler.DDLCompiler):
|
|
|
1503
1749
|
text += "UNIQUE "
|
|
1504
1750
|
if index.dialect_options["oracle"]["bitmap"]:
|
|
1505
1751
|
text += "BITMAP "
|
|
1752
|
+
vector_options = index.dialect_options["oracle"]["vector"]
|
|
1753
|
+
if vector_options:
|
|
1754
|
+
text += "VECTOR "
|
|
1506
1755
|
text += "INDEX %s ON %s (%s)" % (
|
|
1507
1756
|
self._prepared_index_name(index, include_schema=True),
|
|
1508
1757
|
preparer.format_table(index.table, use_schema=True),
|
|
@@ -1520,6 +1769,11 @@ class OracleDDLCompiler(compiler.DDLCompiler):
|
|
|
1520
1769
|
text += " COMPRESS %d" % (
|
|
1521
1770
|
index.dialect_options["oracle"]["compress"]
|
|
1522
1771
|
)
|
|
1772
|
+
if vector_options:
|
|
1773
|
+
if vector_options is True:
|
|
1774
|
+
vector_options = VectorIndexConfig()
|
|
1775
|
+
|
|
1776
|
+
text += " " + self._build_vector_index_config(vector_options)
|
|
1523
1777
|
return text
|
|
1524
1778
|
|
|
1525
1779
|
def post_create_table(self, table):
|
|
@@ -1670,7 +1924,16 @@ class OracleDialect(default.DefaultDialect):
|
|
|
1670
1924
|
"tablespace": None,
|
|
1671
1925
|
},
|
|
1672
1926
|
),
|
|
1673
|
-
(
|
|
1927
|
+
(
|
|
1928
|
+
sa_schema.Index,
|
|
1929
|
+
{
|
|
1930
|
+
"bitmap": False,
|
|
1931
|
+
"compress": False,
|
|
1932
|
+
"vector": False,
|
|
1933
|
+
},
|
|
1934
|
+
),
|
|
1935
|
+
(sa_selectable.Select, {"fetch_approximate": False}),
|
|
1936
|
+
(sa_selectable.CompoundSelect, {"fetch_approximate": False}),
|
|
1674
1937
|
]
|
|
1675
1938
|
|
|
1676
1939
|
@util.deprecated_params(
|