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,311 @@
|
|
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
|
+
Online tests for logger integration
|
17
|
+
|
18
|
+
These tests are inspired by example_09_logger_integration.py
|
19
|
+
"""
|
20
|
+
|
21
|
+
import pytest
|
22
|
+
import logging
|
23
|
+
from matrixone import Client, AsyncClient
|
24
|
+
from matrixone.logger import MatrixOneLogger, create_default_logger, create_custom_logger
|
25
|
+
|
26
|
+
|
27
|
+
@pytest.mark.online
|
28
|
+
class TestLoggerIntegration:
|
29
|
+
"""Test logger integration functionality"""
|
30
|
+
|
31
|
+
def test_default_logger(self, test_client):
|
32
|
+
"""Test default logger configuration"""
|
33
|
+
# Test basic operations with default logger
|
34
|
+
result = test_client.execute("SELECT 1 as test_value")
|
35
|
+
assert result is not None
|
36
|
+
assert result.rows[0][0] == 1
|
37
|
+
|
38
|
+
result = test_client.execute("SELECT VERSION() as version")
|
39
|
+
assert result is not None
|
40
|
+
assert len(result.rows) > 0
|
41
|
+
|
42
|
+
result = test_client.execute("SHOW DATABASES")
|
43
|
+
assert result is not None
|
44
|
+
assert len(result.rows) > 0
|
45
|
+
|
46
|
+
def test_custom_logger(self, connection_params):
|
47
|
+
"""Test custom logger integration"""
|
48
|
+
host, port, user, password, database = connection_params
|
49
|
+
|
50
|
+
# Create custom logger
|
51
|
+
custom_logger_instance = logging.getLogger("test_custom_logger")
|
52
|
+
custom_logger = create_custom_logger(logger=custom_logger_instance, sql_log_mode="auto")
|
53
|
+
|
54
|
+
# Create client with custom logger
|
55
|
+
client = Client(logger=custom_logger)
|
56
|
+
client.connect(host=host, port=port, user=user, password=password, database=database)
|
57
|
+
|
58
|
+
try:
|
59
|
+
# Test operations with custom logger
|
60
|
+
result = client.execute("SELECT 1 as test_value")
|
61
|
+
assert result is not None
|
62
|
+
assert result.rows[0][0] == 1
|
63
|
+
|
64
|
+
result = client.execute("SELECT USER() as user_info")
|
65
|
+
assert result is not None
|
66
|
+
assert len(result.rows) > 0
|
67
|
+
|
68
|
+
finally:
|
69
|
+
client.disconnect()
|
70
|
+
|
71
|
+
def test_performance_logging(self, connection_params):
|
72
|
+
"""Test performance logging"""
|
73
|
+
host, port, user, password, database = connection_params
|
74
|
+
|
75
|
+
# Create logger with SQL logging enabled
|
76
|
+
logger = create_default_logger(sql_log_mode="auto")
|
77
|
+
|
78
|
+
# Create client with SQL logging
|
79
|
+
client = Client(logger=logger)
|
80
|
+
client.connect(host=host, port=port, user=user, password=password, database=database)
|
81
|
+
|
82
|
+
try:
|
83
|
+
# Execute queries to test performance logging
|
84
|
+
result = client.execute("SELECT 1 as test_value")
|
85
|
+
assert result is not None
|
86
|
+
|
87
|
+
# Execute multiple queries to see performance differences
|
88
|
+
for i in range(5):
|
89
|
+
result = client.execute(f"SELECT {i} as test_value")
|
90
|
+
assert result.rows[0][0] == i
|
91
|
+
|
92
|
+
finally:
|
93
|
+
client.disconnect()
|
94
|
+
|
95
|
+
def test_sql_logging(self, connection_params):
|
96
|
+
"""Test SQL query logging"""
|
97
|
+
host, port, user, password, database = connection_params
|
98
|
+
|
99
|
+
# Create logger with full SQL logging enabled
|
100
|
+
logger = create_default_logger(sql_log_mode="full")
|
101
|
+
|
102
|
+
# Create client with full SQL logging
|
103
|
+
client = Client(logger=logger)
|
104
|
+
client.connect(host=host, port=port, user=user, password=password, database=database)
|
105
|
+
|
106
|
+
try:
|
107
|
+
# Execute various SQL queries to test logging
|
108
|
+
client.execute("SELECT 1 as test_value")
|
109
|
+
client.execute("SELECT VERSION() as version")
|
110
|
+
client.execute("SHOW DATABASES")
|
111
|
+
client.execute("SHOW TABLES")
|
112
|
+
|
113
|
+
# Test with parameters (use SQLAlchemy parameter syntax)
|
114
|
+
client.execute("SELECT :param as param_value", {"param": 42})
|
115
|
+
|
116
|
+
finally:
|
117
|
+
client.disconnect()
|
118
|
+
|
119
|
+
def test_structured_logging(self, connection_params):
|
120
|
+
"""Test structured logging"""
|
121
|
+
host, port, user, password, database = connection_params
|
122
|
+
|
123
|
+
# Create structured logger
|
124
|
+
structured_logger_instance = logging.getLogger("structured_logger")
|
125
|
+
logger = create_custom_logger(
|
126
|
+
logger=structured_logger_instance,
|
127
|
+
sql_log_mode="auto",
|
128
|
+
)
|
129
|
+
|
130
|
+
# Create client with structured logger
|
131
|
+
client = Client(logger=logger)
|
132
|
+
client.connect(host=host, port=port, user=user, password=password, database=database)
|
133
|
+
|
134
|
+
try:
|
135
|
+
# Test structured logging with various operations
|
136
|
+
result = client.execute("SELECT 1 as test_value")
|
137
|
+
assert result is not None
|
138
|
+
|
139
|
+
# Test error logging
|
140
|
+
try:
|
141
|
+
client.execute("INVALID SQL")
|
142
|
+
except Exception as e:
|
143
|
+
# Expected to fail, verify it's a SQL error
|
144
|
+
assert "syntax" in str(e).lower() or "error" in str(e).lower()
|
145
|
+
# The error should have been logged by the client
|
146
|
+
|
147
|
+
finally:
|
148
|
+
client.disconnect()
|
149
|
+
|
150
|
+
def test_error_tracking(self, connection_params):
|
151
|
+
"""Test error tracking and logging"""
|
152
|
+
host, port, user, password, database = connection_params
|
153
|
+
|
154
|
+
# Create logger for error tracking
|
155
|
+
logger = create_default_logger(sql_log_mode="auto")
|
156
|
+
|
157
|
+
# Create client with error tracking
|
158
|
+
client = Client(logger=logger)
|
159
|
+
client.connect(host=host, port=port, user=user, password=password, database=database)
|
160
|
+
|
161
|
+
try:
|
162
|
+
# Test successful operations
|
163
|
+
result = client.execute("SELECT 1 as test_value")
|
164
|
+
assert result is not None
|
165
|
+
|
166
|
+
# Test error scenarios that should be logged
|
167
|
+
try:
|
168
|
+
client.execute("SELECT * FROM nonexistent_table")
|
169
|
+
except Exception as e:
|
170
|
+
# Expected to fail, verify it's a table not found error
|
171
|
+
assert "table" in str(e).lower() or "not found" in str(e).lower()
|
172
|
+
# The error should have been logged by the client
|
173
|
+
|
174
|
+
try:
|
175
|
+
client.execute("INVALID SQL SYNTAX")
|
176
|
+
except Exception as e:
|
177
|
+
# Expected to fail, verify it's a syntax error
|
178
|
+
assert "syntax" in str(e).lower() or "error" in str(e).lower()
|
179
|
+
# The error should have been logged by the client
|
180
|
+
|
181
|
+
finally:
|
182
|
+
client.disconnect()
|
183
|
+
|
184
|
+
def test_logger_with_transactions(self, connection_params):
|
185
|
+
"""Test logger with transaction operations"""
|
186
|
+
host, port, user, password, database = connection_params
|
187
|
+
|
188
|
+
# Create logger
|
189
|
+
logger = create_default_logger(sql_log_mode="auto")
|
190
|
+
|
191
|
+
# Create client with logging
|
192
|
+
client = Client(logger=logger)
|
193
|
+
client.connect(host=host, port=port, user=user, password=password, database=database)
|
194
|
+
|
195
|
+
try:
|
196
|
+
# Test transaction logging
|
197
|
+
with client.transaction():
|
198
|
+
client.execute("SELECT 1 as test_value")
|
199
|
+
client.execute("SELECT 2 as test_value")
|
200
|
+
|
201
|
+
# Test rollback logging
|
202
|
+
try:
|
203
|
+
with client.transaction():
|
204
|
+
client.execute("SELECT 1 as test_value")
|
205
|
+
client.execute("INVALID SQL") # This should cause rollback
|
206
|
+
except Exception as e:
|
207
|
+
# Expected to fail and rollback, verify it's a SQL error
|
208
|
+
assert "syntax" in str(e).lower() or "error" in str(e).lower()
|
209
|
+
# The rollback should have been logged by the client
|
210
|
+
|
211
|
+
finally:
|
212
|
+
client.disconnect()
|
213
|
+
|
214
|
+
@pytest.mark.asyncio
|
215
|
+
async def test_async_logger_integration(self, connection_params):
|
216
|
+
"""Test async logger integration"""
|
217
|
+
host, port, user, password, database = connection_params
|
218
|
+
|
219
|
+
# Create logger
|
220
|
+
logger = create_default_logger(sql_log_mode="auto")
|
221
|
+
|
222
|
+
# Create async client with logging
|
223
|
+
client = AsyncClient(logger=logger)
|
224
|
+
await client.connect(host=host, port=port, user=user, password=password, database=database)
|
225
|
+
|
226
|
+
try:
|
227
|
+
# Test async operations with logging
|
228
|
+
result = await client.execute("SELECT 1 as test_value")
|
229
|
+
assert result is not None
|
230
|
+
assert result.rows[0][0] == 1
|
231
|
+
|
232
|
+
result = await client.execute("SELECT VERSION() as version")
|
233
|
+
assert result is not None
|
234
|
+
|
235
|
+
# Test async transaction logging
|
236
|
+
async with client.transaction():
|
237
|
+
await client.execute("SELECT 1 as test_value")
|
238
|
+
await client.execute("SELECT 2 as test_value")
|
239
|
+
|
240
|
+
finally:
|
241
|
+
await client.disconnect()
|
242
|
+
|
243
|
+
def test_logger_configuration_options(self, connection_params):
|
244
|
+
"""Test various logger configuration options"""
|
245
|
+
host, port, user, password, database = connection_params
|
246
|
+
|
247
|
+
# Test different log levels
|
248
|
+
for level in [logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR]:
|
249
|
+
logger_instance = logging.getLogger(f"test_logger_{level}")
|
250
|
+
logger = create_custom_logger(logger=logger_instance, sql_log_mode="auto")
|
251
|
+
|
252
|
+
client = Client(logger=logger)
|
253
|
+
client.connect(host=host, port=port, user=user, password=password, database=database)
|
254
|
+
|
255
|
+
try:
|
256
|
+
result = client.execute("SELECT 1 as test_value")
|
257
|
+
assert result is not None
|
258
|
+
finally:
|
259
|
+
client.disconnect()
|
260
|
+
|
261
|
+
def test_logger_with_different_formats(self, connection_params):
|
262
|
+
"""Test logger with different format strings"""
|
263
|
+
host, port, user, password, database = connection_params
|
264
|
+
|
265
|
+
# Test different format strings
|
266
|
+
formats = [
|
267
|
+
'%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
268
|
+
'%(levelname)s:%(name)s:%(message)s',
|
269
|
+
'%(asctime)s | %(levelname)s | %(message)s',
|
270
|
+
'%(name)s - %(levelname)s - %(message)s',
|
271
|
+
]
|
272
|
+
|
273
|
+
for i, format_string in enumerate(formats):
|
274
|
+
logger_instance = logging.getLogger(f"format_test_{i}")
|
275
|
+
logger = create_custom_logger(logger=logger_instance, sql_log_mode="auto")
|
276
|
+
|
277
|
+
client = Client(logger=logger)
|
278
|
+
client.connect(host=host, port=port, user=user, password=password, database=database)
|
279
|
+
|
280
|
+
try:
|
281
|
+
result = client.execute("SELECT 1 as test_value")
|
282
|
+
assert result is not None
|
283
|
+
finally:
|
284
|
+
client.disconnect()
|
285
|
+
|
286
|
+
def test_matrixone_logger_class(self, connection_params):
|
287
|
+
"""Test MatrixOneLogger class directly"""
|
288
|
+
host, port, user, password, database = connection_params
|
289
|
+
|
290
|
+
# Create MatrixOneLogger instance
|
291
|
+
matrixone_logger = MatrixOneLogger(level=logging.INFO, sql_log_mode="auto")
|
292
|
+
|
293
|
+
# Create client with MatrixOneLogger
|
294
|
+
client = Client(logger=matrixone_logger)
|
295
|
+
client.connect(host=host, port=port, user=user, password=password, database=database)
|
296
|
+
|
297
|
+
try:
|
298
|
+
# Test operations with MatrixOneLogger
|
299
|
+
result = client.execute("SELECT 1 as test_value")
|
300
|
+
assert result is not None
|
301
|
+
|
302
|
+
# Test performance logging
|
303
|
+
result = client.execute("SELECT VERSION() as version")
|
304
|
+
assert result is not None
|
305
|
+
|
306
|
+
# Test SQL logging
|
307
|
+
result = client.execute("SHOW DATABASES")
|
308
|
+
assert result is not None
|
309
|
+
|
310
|
+
finally:
|
311
|
+
client.disconnect()
|