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,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()