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.
Files changed (122) hide show
  1. matrixone/__init__.py +155 -0
  2. matrixone/account.py +723 -0
  3. matrixone/async_client.py +3913 -0
  4. matrixone/async_metadata_manager.py +311 -0
  5. matrixone/async_orm.py +123 -0
  6. matrixone/async_vector_index_manager.py +633 -0
  7. matrixone/base_client.py +208 -0
  8. matrixone/client.py +4672 -0
  9. matrixone/config.py +452 -0
  10. matrixone/connection_hooks.py +286 -0
  11. matrixone/exceptions.py +89 -0
  12. matrixone/logger.py +782 -0
  13. matrixone/metadata.py +820 -0
  14. matrixone/moctl.py +219 -0
  15. matrixone/orm.py +2277 -0
  16. matrixone/pitr.py +646 -0
  17. matrixone/pubsub.py +771 -0
  18. matrixone/restore.py +411 -0
  19. matrixone/search_vector_index.py +1176 -0
  20. matrixone/snapshot.py +550 -0
  21. matrixone/sql_builder.py +844 -0
  22. matrixone/sqlalchemy_ext/__init__.py +161 -0
  23. matrixone/sqlalchemy_ext/adapters.py +163 -0
  24. matrixone/sqlalchemy_ext/dialect.py +534 -0
  25. matrixone/sqlalchemy_ext/fulltext_index.py +895 -0
  26. matrixone/sqlalchemy_ext/fulltext_search.py +1686 -0
  27. matrixone/sqlalchemy_ext/hnsw_config.py +194 -0
  28. matrixone/sqlalchemy_ext/ivf_config.py +252 -0
  29. matrixone/sqlalchemy_ext/table_builder.py +351 -0
  30. matrixone/sqlalchemy_ext/vector_index.py +1721 -0
  31. matrixone/sqlalchemy_ext/vector_type.py +948 -0
  32. matrixone/version.py +580 -0
  33. matrixone_python_sdk-0.1.0.dist-info/METADATA +706 -0
  34. matrixone_python_sdk-0.1.0.dist-info/RECORD +122 -0
  35. matrixone_python_sdk-0.1.0.dist-info/WHEEL +5 -0
  36. matrixone_python_sdk-0.1.0.dist-info/entry_points.txt +5 -0
  37. matrixone_python_sdk-0.1.0.dist-info/licenses/LICENSE +200 -0
  38. matrixone_python_sdk-0.1.0.dist-info/top_level.txt +2 -0
  39. tests/__init__.py +19 -0
  40. tests/offline/__init__.py +20 -0
  41. tests/offline/conftest.py +77 -0
  42. tests/offline/test_account.py +703 -0
  43. tests/offline/test_async_client_query_comprehensive.py +1218 -0
  44. tests/offline/test_basic.py +54 -0
  45. tests/offline/test_case_sensitivity.py +227 -0
  46. tests/offline/test_connection_hooks_offline.py +287 -0
  47. tests/offline/test_dialect_schema_handling.py +609 -0
  48. tests/offline/test_explain_methods.py +346 -0
  49. tests/offline/test_filter_logical_in.py +237 -0
  50. tests/offline/test_fulltext_search_comprehensive.py +795 -0
  51. tests/offline/test_ivf_config.py +249 -0
  52. tests/offline/test_join_methods.py +281 -0
  53. tests/offline/test_join_sqlalchemy_compatibility.py +276 -0
  54. tests/offline/test_logical_in_method.py +237 -0
  55. tests/offline/test_matrixone_version_parsing.py +264 -0
  56. tests/offline/test_metadata_offline.py +557 -0
  57. tests/offline/test_moctl.py +300 -0
  58. tests/offline/test_moctl_simple.py +251 -0
  59. tests/offline/test_model_support_offline.py +359 -0
  60. tests/offline/test_model_support_simple.py +225 -0
  61. tests/offline/test_pinecone_filter_offline.py +377 -0
  62. tests/offline/test_pitr.py +585 -0
  63. tests/offline/test_pubsub.py +712 -0
  64. tests/offline/test_query_update.py +283 -0
  65. tests/offline/test_restore.py +445 -0
  66. tests/offline/test_snapshot_comprehensive.py +384 -0
  67. tests/offline/test_sql_escaping_edge_cases.py +551 -0
  68. tests/offline/test_sqlalchemy_integration.py +382 -0
  69. tests/offline/test_sqlalchemy_vector_integration.py +434 -0
  70. tests/offline/test_table_builder.py +198 -0
  71. tests/offline/test_unified_filter.py +398 -0
  72. tests/offline/test_unified_transaction.py +495 -0
  73. tests/offline/test_vector_index.py +238 -0
  74. tests/offline/test_vector_operations.py +688 -0
  75. tests/offline/test_vector_type.py +174 -0
  76. tests/offline/test_version_core.py +328 -0
  77. tests/offline/test_version_management.py +372 -0
  78. tests/offline/test_version_standalone.py +652 -0
  79. tests/online/__init__.py +20 -0
  80. tests/online/conftest.py +216 -0
  81. tests/online/test_account_management.py +194 -0
  82. tests/online/test_advanced_features.py +344 -0
  83. tests/online/test_async_client_interfaces.py +330 -0
  84. tests/online/test_async_client_online.py +285 -0
  85. tests/online/test_async_model_insert_online.py +293 -0
  86. tests/online/test_async_orm_online.py +300 -0
  87. tests/online/test_async_simple_query_online.py +802 -0
  88. tests/online/test_async_transaction_simple_query.py +300 -0
  89. tests/online/test_basic_connection.py +130 -0
  90. tests/online/test_client_online.py +238 -0
  91. tests/online/test_config.py +90 -0
  92. tests/online/test_config_validation.py +123 -0
  93. tests/online/test_connection_hooks_new_online.py +217 -0
  94. tests/online/test_dialect_schema_handling_online.py +331 -0
  95. tests/online/test_filter_logical_in_online.py +374 -0
  96. tests/online/test_fulltext_comprehensive.py +1773 -0
  97. tests/online/test_fulltext_label_online.py +433 -0
  98. tests/online/test_fulltext_search_online.py +842 -0
  99. tests/online/test_ivf_stats_online.py +506 -0
  100. tests/online/test_logger_integration.py +311 -0
  101. tests/online/test_matrixone_query_orm.py +540 -0
  102. tests/online/test_metadata_online.py +579 -0
  103. tests/online/test_model_insert_online.py +255 -0
  104. tests/online/test_mysql_driver_validation.py +213 -0
  105. tests/online/test_orm_advanced_features.py +2022 -0
  106. tests/online/test_orm_cte_integration.py +269 -0
  107. tests/online/test_orm_online.py +270 -0
  108. tests/online/test_pinecone_filter.py +708 -0
  109. tests/online/test_pubsub_operations.py +352 -0
  110. tests/online/test_query_methods.py +225 -0
  111. tests/online/test_query_update_online.py +433 -0
  112. tests/online/test_search_vector_index.py +557 -0
  113. tests/online/test_simple_fulltext_online.py +915 -0
  114. tests/online/test_snapshot_comprehensive.py +998 -0
  115. tests/online/test_sqlalchemy_engine_integration.py +336 -0
  116. tests/online/test_sqlalchemy_integration.py +425 -0
  117. tests/online/test_transaction_contexts.py +1219 -0
  118. tests/online/test_transaction_insert_methods.py +356 -0
  119. tests/online/test_transaction_query_methods.py +288 -0
  120. tests/online/test_unified_filter_online.py +529 -0
  121. tests/online/test_vector_comprehensive.py +706 -0
  122. tests/online/test_version_management.py +291 -0
@@ -0,0 +1,351 @@
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
+ Table builder utilities for MatrixOne vector tables.
17
+ """
18
+
19
+ from typing import List, Optional, Union
20
+
21
+ from sqlalchemy import (
22
+ TIMESTAMP,
23
+ BigInteger,
24
+ Boolean,
25
+ Column,
26
+ Date,
27
+ DateTime,
28
+ ForeignKeyConstraint,
29
+ Index,
30
+ Integer,
31
+ MetaData,
32
+ Numeric,
33
+ PrimaryKeyConstraint,
34
+ SmallInteger,
35
+ String,
36
+ Table,
37
+ Text,
38
+ Time,
39
+ )
40
+ from sqlalchemy.dialects.mysql import BLOB, JSON, LONGBLOB, MEDIUMBLOB, TINYBLOB, TINYINT, VARBINARY
41
+
42
+ from .vector_type import Vectorf32, Vectorf64, VectorPrecision, VectorType
43
+
44
+
45
+ class VectorTableBuilder:
46
+ """
47
+ Builder class for creating MatrixOne vector tables with SQLAlchemy.
48
+
49
+ This class provides a fluent interface for building vector tables with
50
+ proper column definitions, indexes, and constraints. It's designed to
51
+ work seamlessly with MatrixOne's vector capabilities and SQLAlchemy.
52
+
53
+ Key Features:
54
+
55
+ - Fluent method chaining for table definition
56
+ - Support for all MatrixOne column types including vectors
57
+ - Automatic vector index creation
58
+ - Constraint and foreign key support
59
+ - Integration with SQLAlchemy metadata
60
+
61
+ Supported Column Types:
62
+ - Standard types: Integer, String, Text, DateTime, etc.
63
+ - Vector types: Vectorf32, Vectorf64 with configurable dimensions
64
+ - MatrixOne-specific types: JSON, BLOB variants
65
+
66
+ Usage Examples
67
+
68
+ .. code-block:: python
69
+
70
+ # Create a simple vector table
71
+ builder = VectorTableBuilder('documents')
72
+ table = (builder
73
+ .add_int_column('id', primary_key=True)
74
+ .add_string_column('title', length=255)
75
+ .add_text_column('content')
76
+ .add_vector_column('embedding', Vectorf32(384))
77
+ .build())
78
+
79
+ # Create a complex table with indexes
80
+ builder = VectorTableBuilder('products')
81
+ table = (builder
82
+ .add_bigint_column('id', primary_key=True)
83
+ .add_string_column('name', length=100)
84
+ .add_numeric_column('price', precision=10, scale=2)
85
+ .add_vector_column('features', Vectorf64(512))
86
+ .add_vector_index('idx_features', 'features', 'ivfflat', lists=100)
87
+ .build())
88
+
89
+ Note: This builder is primarily used internally by the Client's table
90
+ creation methods, but can be used directly for advanced use cases.
91
+ """
92
+
93
+ def __init__(self, table_name: str, metadata: MetaData = None):
94
+ """
95
+ Initialize the table builder.
96
+
97
+ Args:
98
+
99
+ table_name: Name of the table to create
100
+ metadata: SQLAlchemy metadata object
101
+ """
102
+ self.table_name = table_name
103
+ self.metadata = metadata or MetaData()
104
+ self.columns = []
105
+ self.indexes = []
106
+ self.constraints = []
107
+
108
+ def add_column(self, name: str, type_, **kwargs):
109
+ """Add a column to the table."""
110
+ column = Column(name, type_, **kwargs)
111
+ self.columns.append(column)
112
+ return self
113
+
114
+ def add_int_column(self, name: str, primary_key: bool = False, **kwargs):
115
+ """Add an integer column."""
116
+ if primary_key:
117
+ kwargs["primary_key"] = True
118
+ return self.add_column(name, Integer, **kwargs)
119
+
120
+ def add_bigint_column(self, name: str, primary_key: bool = False, **kwargs):
121
+ """Add a bigint column."""
122
+ if primary_key:
123
+ kwargs["primary_key"] = True
124
+ return self.add_column(name, BigInteger, **kwargs)
125
+
126
+ def add_string_column(self, name: str, length: int = 255, **kwargs):
127
+ """Add a string column."""
128
+ return self.add_column(name, String(length), **kwargs)
129
+
130
+ def add_text_column(self, name: str, **kwargs):
131
+ """Add a text column."""
132
+ return self.add_column(name, Text, **kwargs)
133
+
134
+ def add_json_column(self, name: str, **kwargs):
135
+ """Add a JSON column."""
136
+ return self.add_column(name, JSON, **kwargs)
137
+
138
+ def add_vector_column(self, name: str, dimension: int, precision: str = VectorPrecision.F32, **kwargs):
139
+ """Add a vector column."""
140
+ if precision == VectorPrecision.F32:
141
+ vector_type = Vectorf32(dimension=dimension)
142
+ elif precision == VectorPrecision.F64:
143
+ vector_type = Vectorf64(dimension=dimension)
144
+ else:
145
+ vector_type = VectorType(dimension=dimension, precision=precision)
146
+
147
+ return self.add_column(name, vector_type, **kwargs)
148
+
149
+ def add_vecf32_column(self, name: str, dimension: int, **kwargs):
150
+ """Add a vecf32 column."""
151
+ return self.add_vector_column(name, dimension, VectorPrecision.F32, **kwargs)
152
+
153
+ def add_vecf64_column(self, name: str, dimension: int, **kwargs):
154
+ """Add a vecf64 column."""
155
+ return self.add_vector_column(name, dimension, VectorPrecision.F64, **kwargs)
156
+
157
+ def add_smallint_column(self, name: str, primary_key: bool = False, **kwargs):
158
+ """Add a smallint column."""
159
+ if primary_key:
160
+ kwargs["primary_key"] = True
161
+ return self.add_column(name, SmallInteger, **kwargs)
162
+
163
+ def add_tinyint_column(self, name: str, primary_key: bool = False, **kwargs):
164
+ """Add a tinyint column."""
165
+ if primary_key:
166
+ kwargs["primary_key"] = True
167
+ return self.add_column(name, TINYINT, **kwargs)
168
+
169
+ def add_numeric_column(
170
+ self, name: str, column_type: str, precision: Optional[int] = None, scale: Optional[int] = None, **kwargs
171
+ ):
172
+ """Add a numeric column (float, double, decimal, numeric)."""
173
+ if column_type in ("float", "double"):
174
+ from sqlalchemy import Float
175
+
176
+ return self.add_column(name, Float(precision=precision), **kwargs)
177
+ elif column_type in ("decimal", "numeric"):
178
+ return self.add_column(name, Numeric(precision=precision, scale=scale), **kwargs)
179
+ else:
180
+ raise ValueError(f"Unsupported numeric type: {column_type}")
181
+
182
+ def add_datetime_column(self, name: str, column_type: str, **kwargs):
183
+ """Add a datetime column (date, datetime, timestamp, time, year)."""
184
+ if column_type == "date":
185
+ return self.add_column(name, Date, **kwargs)
186
+ elif column_type == "datetime":
187
+ return self.add_column(name, DateTime, **kwargs)
188
+ elif column_type == "timestamp":
189
+ return self.add_column(name, TIMESTAMP, **kwargs)
190
+ elif column_type == "time":
191
+ return self.add_column(name, Time, **kwargs)
192
+ elif column_type == "year":
193
+ # MySQL YEAR type
194
+ from sqlalchemy.dialects.mysql import YEAR
195
+
196
+ return self.add_column(name, YEAR, **kwargs)
197
+ else:
198
+ raise ValueError(f"Unsupported datetime type: {column_type}")
199
+
200
+ def add_boolean_column(self, name: str, **kwargs):
201
+ """Add a boolean column."""
202
+ return self.add_column(name, Boolean, **kwargs)
203
+
204
+ def add_binary_column(self, name: str, column_type: str, **kwargs):
205
+ """Add a binary column (blob, longblob, mediumblob, tinyblob, binary, varbinary)."""
206
+ if column_type == "blob":
207
+ return self.add_column(name, BLOB, **kwargs)
208
+ elif column_type == "longblob":
209
+ return self.add_column(name, LONGBLOB, **kwargs)
210
+ elif column_type == "mediumblob":
211
+ return self.add_column(name, MEDIUMBLOB, **kwargs)
212
+ elif column_type == "tinyblob":
213
+ return self.add_column(name, TINYBLOB, **kwargs)
214
+ elif column_type == "binary":
215
+ from sqlalchemy import Binary
216
+
217
+ return self.add_column(name, Binary, **kwargs)
218
+ elif column_type == "varbinary":
219
+ return self.add_column(name, VARBINARY, **kwargs)
220
+ else:
221
+ raise ValueError(f"Unsupported binary type: {column_type}")
222
+
223
+ def add_enum_column(self, name: str, column_type: str, values: list, **kwargs):
224
+ """Add an enum or set column."""
225
+ if column_type == "enum":
226
+ from sqlalchemy import Enum
227
+
228
+ return self.add_column(name, Enum(*values), **kwargs)
229
+ elif column_type == "set":
230
+ from sqlalchemy.dialects.mysql import SET
231
+
232
+ return self.add_column(name, SET(*values), **kwargs)
233
+ else:
234
+ raise ValueError(f"Unsupported enum type: {column_type}")
235
+
236
+ def add_index(self, columns: Union[str, List[str]], name: Optional[str] = None, **kwargs):
237
+ """Add an index to the table."""
238
+ if isinstance(columns, str):
239
+ columns = [columns]
240
+
241
+ index_name = name or f"idx_{self.table_name}_{'_'.join(columns)}"
242
+ index = Index(index_name, *columns, **kwargs)
243
+ self.indexes.append(index)
244
+ return self
245
+
246
+ def add_primary_key(self, columns: Union[str, List[str]]):
247
+ """Add a primary key constraint."""
248
+ if isinstance(columns, str):
249
+ columns = [columns]
250
+ constraint = PrimaryKeyConstraint(*columns)
251
+ self.constraints.append(constraint)
252
+ return self
253
+
254
+ def add_foreign_key(
255
+ self,
256
+ columns: Union[str, List[str]],
257
+ ref_table: str,
258
+ ref_columns: Union[str, List[str]],
259
+ name: Optional[str] = None,
260
+ ):
261
+ """Add a foreign key constraint."""
262
+ if isinstance(columns, str):
263
+ columns = [columns]
264
+ if isinstance(ref_columns, str):
265
+ ref_columns = [ref_columns]
266
+
267
+ constraint_name = name or f"fk_{self.table_name}_{'_'.join(columns)}"
268
+ constraint = ForeignKeyConstraint(columns, [f"{ref_table}.{col}" for col in ref_columns], name=constraint_name)
269
+ self.constraints.append(constraint)
270
+ return self
271
+
272
+ def build(self) -> Table:
273
+ """Build and return the SQLAlchemy Table object."""
274
+ return Table(self.table_name, self.metadata, *self.columns, *self.indexes, *self.constraints)
275
+
276
+
277
+ def create_vector_table(table_name: str, metadata: MetaData = None) -> VectorTableBuilder:
278
+ """
279
+ Create a new vector table builder.
280
+
281
+ Args:
282
+
283
+ table_name: Name of the table
284
+ metadata: SQLAlchemy metadata object
285
+
286
+ Returns:
287
+
288
+ VectorTableBuilder instance
289
+ """
290
+ return VectorTableBuilder(table_name, metadata)
291
+
292
+
293
+ # Convenience functions for common table patterns
294
+ def create_vector_index_table(table_name: str, metadata: MetaData = None) -> VectorTableBuilder:
295
+ """
296
+ Create a table builder for vector index tables.
297
+
298
+ Example: create table vector_index_07(a int primary key, b vecf32(128), c int, key c_k(c))
299
+ """
300
+ builder = VectorTableBuilder(table_name, metadata)
301
+
302
+ # Add common columns
303
+ builder.add_int_column("a", primary_key=True)
304
+ builder.add_vecf32_column("b", dimension=128)
305
+ builder.add_int_column("c")
306
+
307
+ # Add index on column c
308
+ builder.add_index("c", name="c_k")
309
+
310
+ return builder
311
+
312
+
313
+ def create_document_vector_table(table_name: str, metadata: MetaData = None, vector_dim: int = 384) -> VectorTableBuilder:
314
+ """
315
+ Create a table builder for document vector storage.
316
+ """
317
+ builder = VectorTableBuilder(table_name, metadata)
318
+
319
+ builder.add_int_column("id", primary_key=True, autoincrement=True)
320
+ builder.add_string_column("document_id", length=100, nullable=False, unique=True)
321
+ builder.add_string_column("title", length=255)
322
+ builder.add_text_column("content")
323
+ builder.add_vecf32_column("embedding", dimension=vector_dim, nullable=False)
324
+ builder.add_json_column("metadata")
325
+
326
+ # Add indexes
327
+ builder.add_index("document_id")
328
+ builder.add_index("title")
329
+
330
+ return builder
331
+
332
+
333
+ def create_product_vector_table(table_name: str, metadata: MetaData = None, vector_dim: int = 512) -> VectorTableBuilder:
334
+ """
335
+ Create a table builder for product vector storage.
336
+ """
337
+ builder = VectorTableBuilder(table_name, metadata)
338
+
339
+ builder.add_int_column("id", primary_key=True, autoincrement=True)
340
+ builder.add_string_column("product_id", length=50, nullable=False, unique=True)
341
+ builder.add_string_column("name", length=200)
342
+ builder.add_text_column("description")
343
+ builder.add_vecf32_column("embedding", dimension=vector_dim, nullable=False)
344
+ builder.add_string_column("category", length=100)
345
+ builder.add_string_column("price", length=20)
346
+
347
+ # Add indexes
348
+ builder.add_index("product_id")
349
+ builder.add_index("category")
350
+
351
+ return builder