matrixone-python-sdk 0.1.0__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.
- matrixone/__init__.py +155 -0
- matrixone/account.py +723 -0
- matrixone/async_client.py +3913 -0
- matrixone/async_metadata_manager.py +311 -0
- matrixone/async_orm.py +123 -0
- matrixone/async_vector_index_manager.py +633 -0
- matrixone/base_client.py +208 -0
- matrixone/client.py +4672 -0
- matrixone/config.py +452 -0
- matrixone/connection_hooks.py +286 -0
- matrixone/exceptions.py +89 -0
- matrixone/logger.py +782 -0
- matrixone/metadata.py +820 -0
- matrixone/moctl.py +219 -0
- matrixone/orm.py +2277 -0
- matrixone/pitr.py +646 -0
- matrixone/pubsub.py +771 -0
- matrixone/restore.py +411 -0
- matrixone/search_vector_index.py +1176 -0
- matrixone/snapshot.py +550 -0
- matrixone/sql_builder.py +844 -0
- matrixone/sqlalchemy_ext/__init__.py +161 -0
- matrixone/sqlalchemy_ext/adapters.py +163 -0
- matrixone/sqlalchemy_ext/dialect.py +534 -0
- matrixone/sqlalchemy_ext/fulltext_index.py +895 -0
- matrixone/sqlalchemy_ext/fulltext_search.py +1686 -0
- matrixone/sqlalchemy_ext/hnsw_config.py +194 -0
- matrixone/sqlalchemy_ext/ivf_config.py +252 -0
- matrixone/sqlalchemy_ext/table_builder.py +351 -0
- matrixone/sqlalchemy_ext/vector_index.py +1721 -0
- matrixone/sqlalchemy_ext/vector_type.py +948 -0
- matrixone/version.py +580 -0
- matrixone_python_sdk-0.1.0.dist-info/METADATA +706 -0
- matrixone_python_sdk-0.1.0.dist-info/RECORD +122 -0
- matrixone_python_sdk-0.1.0.dist-info/WHEEL +5 -0
- matrixone_python_sdk-0.1.0.dist-info/entry_points.txt +5 -0
- matrixone_python_sdk-0.1.0.dist-info/licenses/LICENSE +200 -0
- matrixone_python_sdk-0.1.0.dist-info/top_level.txt +2 -0
- tests/__init__.py +19 -0
- tests/offline/__init__.py +20 -0
- tests/offline/conftest.py +77 -0
- tests/offline/test_account.py +703 -0
- tests/offline/test_async_client_query_comprehensive.py +1218 -0
- tests/offline/test_basic.py +54 -0
- tests/offline/test_case_sensitivity.py +227 -0
- tests/offline/test_connection_hooks_offline.py +287 -0
- tests/offline/test_dialect_schema_handling.py +609 -0
- tests/offline/test_explain_methods.py +346 -0
- tests/offline/test_filter_logical_in.py +237 -0
- tests/offline/test_fulltext_search_comprehensive.py +795 -0
- tests/offline/test_ivf_config.py +249 -0
- tests/offline/test_join_methods.py +281 -0
- tests/offline/test_join_sqlalchemy_compatibility.py +276 -0
- tests/offline/test_logical_in_method.py +237 -0
- tests/offline/test_matrixone_version_parsing.py +264 -0
- tests/offline/test_metadata_offline.py +557 -0
- tests/offline/test_moctl.py +300 -0
- tests/offline/test_moctl_simple.py +251 -0
- tests/offline/test_model_support_offline.py +359 -0
- tests/offline/test_model_support_simple.py +225 -0
- tests/offline/test_pinecone_filter_offline.py +377 -0
- tests/offline/test_pitr.py +585 -0
- tests/offline/test_pubsub.py +712 -0
- tests/offline/test_query_update.py +283 -0
- tests/offline/test_restore.py +445 -0
- tests/offline/test_snapshot_comprehensive.py +384 -0
- tests/offline/test_sql_escaping_edge_cases.py +551 -0
- tests/offline/test_sqlalchemy_integration.py +382 -0
- tests/offline/test_sqlalchemy_vector_integration.py +434 -0
- tests/offline/test_table_builder.py +198 -0
- tests/offline/test_unified_filter.py +398 -0
- tests/offline/test_unified_transaction.py +495 -0
- tests/offline/test_vector_index.py +238 -0
- tests/offline/test_vector_operations.py +688 -0
- tests/offline/test_vector_type.py +174 -0
- tests/offline/test_version_core.py +328 -0
- tests/offline/test_version_management.py +372 -0
- tests/offline/test_version_standalone.py +652 -0
- tests/online/__init__.py +20 -0
- tests/online/conftest.py +216 -0
- tests/online/test_account_management.py +194 -0
- tests/online/test_advanced_features.py +344 -0
- tests/online/test_async_client_interfaces.py +330 -0
- tests/online/test_async_client_online.py +285 -0
- tests/online/test_async_model_insert_online.py +293 -0
- tests/online/test_async_orm_online.py +300 -0
- tests/online/test_async_simple_query_online.py +802 -0
- tests/online/test_async_transaction_simple_query.py +300 -0
- tests/online/test_basic_connection.py +130 -0
- tests/online/test_client_online.py +238 -0
- tests/online/test_config.py +90 -0
- tests/online/test_config_validation.py +123 -0
- tests/online/test_connection_hooks_new_online.py +217 -0
- tests/online/test_dialect_schema_handling_online.py +331 -0
- tests/online/test_filter_logical_in_online.py +374 -0
- tests/online/test_fulltext_comprehensive.py +1773 -0
- tests/online/test_fulltext_label_online.py +433 -0
- tests/online/test_fulltext_search_online.py +842 -0
- tests/online/test_ivf_stats_online.py +506 -0
- tests/online/test_logger_integration.py +311 -0
- tests/online/test_matrixone_query_orm.py +540 -0
- tests/online/test_metadata_online.py +579 -0
- tests/online/test_model_insert_online.py +255 -0
- tests/online/test_mysql_driver_validation.py +213 -0
- tests/online/test_orm_advanced_features.py +2022 -0
- tests/online/test_orm_cte_integration.py +269 -0
- tests/online/test_orm_online.py +270 -0
- tests/online/test_pinecone_filter.py +708 -0
- tests/online/test_pubsub_operations.py +352 -0
- tests/online/test_query_methods.py +225 -0
- tests/online/test_query_update_online.py +433 -0
- tests/online/test_search_vector_index.py +557 -0
- tests/online/test_simple_fulltext_online.py +915 -0
- tests/online/test_snapshot_comprehensive.py +998 -0
- tests/online/test_sqlalchemy_engine_integration.py +336 -0
- tests/online/test_sqlalchemy_integration.py +425 -0
- tests/online/test_transaction_contexts.py +1219 -0
- tests/online/test_transaction_insert_methods.py +356 -0
- tests/online/test_transaction_query_methods.py +288 -0
- tests/online/test_unified_filter_online.py +529 -0
- tests/online/test_vector_comprehensive.py +706 -0
- tests/online/test_version_management.py +291 -0
@@ -0,0 +1,238 @@
|
|
1
|
+
# Copyright 2021 - 2022 Matrix Origin
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
"""
|
16
|
+
Offline tests for vector index functionality.
|
17
|
+
"""
|
18
|
+
|
19
|
+
import pytest
|
20
|
+
from unittest.mock import Mock, patch
|
21
|
+
from sqlalchemy import Table, Column, Integer, String, MetaData
|
22
|
+
from sqlalchemy.schema import CreateTable
|
23
|
+
|
24
|
+
from matrixone.sqlalchemy_ext import (
|
25
|
+
VectorIndex,
|
26
|
+
VectorIndexType,
|
27
|
+
VectorOpType,
|
28
|
+
CreateVectorIndex,
|
29
|
+
create_vector_index,
|
30
|
+
create_ivfflat_index,
|
31
|
+
vector_index_builder,
|
32
|
+
create_vector_column,
|
33
|
+
Vectorf32,
|
34
|
+
)
|
35
|
+
|
36
|
+
|
37
|
+
class TestVectorIndexOffline:
|
38
|
+
"""Test vector index functionality using mocks."""
|
39
|
+
|
40
|
+
def test_vector_index_creation(self):
|
41
|
+
"""Test creating vector indexes."""
|
42
|
+
# Test basic vector index
|
43
|
+
index = VectorIndex(
|
44
|
+
"idx_test",
|
45
|
+
"embedding",
|
46
|
+
index_type=VectorIndexType.IVFFLAT,
|
47
|
+
lists=256,
|
48
|
+
op_type=VectorOpType.VECTOR_L2_OPS,
|
49
|
+
)
|
50
|
+
|
51
|
+
assert index.name == "idx_test"
|
52
|
+
assert index.index_type == VectorIndexType.IVFFLAT
|
53
|
+
assert index.lists == 256
|
54
|
+
assert index.op_type == VectorOpType.VECTOR_L2_OPS
|
55
|
+
|
56
|
+
def test_create_vector_index_helper(self):
|
57
|
+
"""Test create_vector_index helper function."""
|
58
|
+
index = create_vector_index(
|
59
|
+
"idx_helper",
|
60
|
+
"embedding",
|
61
|
+
index_type=VectorIndexType.IVFFLAT,
|
62
|
+
lists=128,
|
63
|
+
op_type=VectorOpType.VECTOR_COSINE_OPS,
|
64
|
+
)
|
65
|
+
|
66
|
+
assert index.name == "idx_helper"
|
67
|
+
assert index.index_type == VectorIndexType.IVFFLAT
|
68
|
+
assert index.lists == 128
|
69
|
+
assert index.op_type == VectorOpType.VECTOR_COSINE_OPS
|
70
|
+
|
71
|
+
def test_create_ivfflat_index_helper(self):
|
72
|
+
"""Test create_ivfflat_index helper function."""
|
73
|
+
index = create_ivfflat_index("idx_ivfflat", "embedding", lists=64, op_type=VectorOpType.VECTOR_L2_OPS)
|
74
|
+
|
75
|
+
assert index.name == "idx_ivfflat"
|
76
|
+
assert index.index_type == VectorIndexType.IVFFLAT
|
77
|
+
assert index.lists == 64
|
78
|
+
assert index.op_type == VectorOpType.VECTOR_L2_OPS
|
79
|
+
|
80
|
+
def test_vector_index_sql_generation(self):
|
81
|
+
"""Test vector index SQL generation."""
|
82
|
+
index = VectorIndex(
|
83
|
+
"idx_sql_test",
|
84
|
+
"embedding",
|
85
|
+
index_type=VectorIndexType.IVFFLAT,
|
86
|
+
lists=256,
|
87
|
+
op_type=VectorOpType.VECTOR_L2_OPS,
|
88
|
+
)
|
89
|
+
|
90
|
+
# Mock table
|
91
|
+
mock_table = Mock()
|
92
|
+
mock_table.name = "test_table"
|
93
|
+
index.table = mock_table
|
94
|
+
|
95
|
+
# Test SQL generation
|
96
|
+
sql = index._create_index_sql("test_table")
|
97
|
+
expected_parts = [
|
98
|
+
"CREATE INDEX idx_sql_test USING ivfflat ON test_table(embedding)",
|
99
|
+
"lists = 256",
|
100
|
+
"op_type 'vector_l2_ops'",
|
101
|
+
]
|
102
|
+
|
103
|
+
for part in expected_parts:
|
104
|
+
assert part in sql
|
105
|
+
|
106
|
+
def test_vector_index_builder(self):
|
107
|
+
"""Test VectorIndexBuilder functionality."""
|
108
|
+
builder = vector_index_builder("embedding")
|
109
|
+
|
110
|
+
# Add multiple indexes
|
111
|
+
indexes = (
|
112
|
+
builder.l2_index("idx_l2", lists=256).cosine_index("idx_cosine", lists=128).ip_index("idx_ip", lists=192).build()
|
113
|
+
)
|
114
|
+
|
115
|
+
assert len(indexes) == 3
|
116
|
+
|
117
|
+
# Check L2 index
|
118
|
+
l2_idx = indexes[0]
|
119
|
+
assert l2_idx.name == "idx_l2"
|
120
|
+
assert l2_idx.lists == 256
|
121
|
+
assert l2_idx.op_type == VectorOpType.VECTOR_L2_OPS
|
122
|
+
|
123
|
+
# Check cosine index
|
124
|
+
cosine_idx = indexes[1]
|
125
|
+
assert cosine_idx.name == "idx_cosine"
|
126
|
+
assert cosine_idx.lists == 128
|
127
|
+
assert cosine_idx.op_type == VectorOpType.VECTOR_COSINE_OPS
|
128
|
+
|
129
|
+
# Check IP index
|
130
|
+
ip_idx = indexes[2]
|
131
|
+
assert ip_idx.name == "idx_ip"
|
132
|
+
assert ip_idx.lists == 192
|
133
|
+
assert ip_idx.op_type == VectorOpType.VECTOR_IP_OPS
|
134
|
+
|
135
|
+
def test_vector_index_with_table(self):
|
136
|
+
"""Test vector index integration with SQLAlchemy Table."""
|
137
|
+
# Create metadata and table
|
138
|
+
metadata = MetaData()
|
139
|
+
table = Table(
|
140
|
+
'vector_docs',
|
141
|
+
metadata,
|
142
|
+
Column('id', Integer, primary_key=True),
|
143
|
+
Column('embedding', Vectorf32(dimension=128)),
|
144
|
+
Column('title', String(200)),
|
145
|
+
)
|
146
|
+
|
147
|
+
# Create vector index
|
148
|
+
index = create_ivfflat_index("idx_embedding", "embedding", lists=256, op_type=VectorOpType.VECTOR_L2_OPS)
|
149
|
+
|
150
|
+
# Add index to table
|
151
|
+
index.table = table
|
152
|
+
table.indexes.add(index)
|
153
|
+
|
154
|
+
# Verify index is added
|
155
|
+
assert len(table.indexes) == 1
|
156
|
+
assert index in table.indexes
|
157
|
+
|
158
|
+
def test_create_vector_index_ddl(self):
|
159
|
+
"""Test CreateVectorIndex DDL compilation."""
|
160
|
+
index = VectorIndex(
|
161
|
+
"idx_ddl_test",
|
162
|
+
"embedding",
|
163
|
+
index_type=VectorIndexType.IVFFLAT,
|
164
|
+
lists=128,
|
165
|
+
op_type=VectorOpType.VECTOR_COSINE_OPS,
|
166
|
+
)
|
167
|
+
|
168
|
+
# Mock table
|
169
|
+
mock_table = Mock()
|
170
|
+
mock_table.name = "test_table"
|
171
|
+
index.table = mock_table
|
172
|
+
|
173
|
+
# Create DDL element
|
174
|
+
ddl = CreateVectorIndex(index)
|
175
|
+
|
176
|
+
# Test that DDL element is created
|
177
|
+
assert ddl.index == index
|
178
|
+
assert ddl.if_not_exists is False
|
179
|
+
|
180
|
+
def test_vector_index_types(self):
|
181
|
+
"""Test vector index type constants."""
|
182
|
+
assert VectorIndexType.IVFFLAT == "ivfflat"
|
183
|
+
assert VectorIndexType.HNSW == "hnsw"
|
184
|
+
|
185
|
+
assert VectorOpType.VECTOR_L2_OPS == "vector_l2_ops"
|
186
|
+
assert VectorOpType.VECTOR_COSINE_OPS == "vector_cosine_ops"
|
187
|
+
assert VectorOpType.VECTOR_IP_OPS == "vector_ip_ops"
|
188
|
+
|
189
|
+
def test_vector_index_parameters(self):
|
190
|
+
"""Test vector index with different parameters."""
|
191
|
+
# Test without lists parameter
|
192
|
+
index1 = VectorIndex(
|
193
|
+
"idx_no_lists",
|
194
|
+
"embedding",
|
195
|
+
index_type=VectorIndexType.IVFFLAT,
|
196
|
+
op_type=VectorOpType.VECTOR_L2_OPS,
|
197
|
+
)
|
198
|
+
|
199
|
+
assert index1.lists is None
|
200
|
+
|
201
|
+
# Test with standard parameters
|
202
|
+
index2 = VectorIndex(
|
203
|
+
"idx_standard",
|
204
|
+
"embedding",
|
205
|
+
index_type=VectorIndexType.IVFFLAT,
|
206
|
+
lists=512,
|
207
|
+
op_type=VectorOpType.VECTOR_COSINE_OPS,
|
208
|
+
)
|
209
|
+
|
210
|
+
assert index2.lists == 512
|
211
|
+
assert index2.op_type == VectorOpType.VECTOR_COSINE_OPS
|
212
|
+
|
213
|
+
def test_vector_index_builder_chain(self):
|
214
|
+
"""Test VectorIndexBuilder method chaining."""
|
215
|
+
builder = vector_index_builder("embedding")
|
216
|
+
|
217
|
+
# Test method chaining
|
218
|
+
result = builder.l2_index("idx1", lists=100).cosine_index("idx2", lists=200).ip_index("idx3", lists=300)
|
219
|
+
|
220
|
+
# Should return self for chaining
|
221
|
+
assert result is builder
|
222
|
+
|
223
|
+
# Build indexes
|
224
|
+
indexes = builder.build()
|
225
|
+
assert len(indexes) == 3
|
226
|
+
|
227
|
+
def test_vector_index_with_column_object(self):
|
228
|
+
"""Test vector index with Column object instead of string."""
|
229
|
+
# Create a vector column
|
230
|
+
vector_col = create_vector_column(128, "f32")
|
231
|
+
vector_col.name = "embedding"
|
232
|
+
|
233
|
+
# Create index with column object
|
234
|
+
index = create_ivfflat_index("idx_column_obj", vector_col, lists=256, op_type=VectorOpType.VECTOR_L2_OPS)
|
235
|
+
|
236
|
+
assert index.name == "idx_column_obj"
|
237
|
+
assert index.lists == 256
|
238
|
+
assert index.op_type == VectorOpType.VECTOR_L2_OPS
|