pyseekdb 0.1.0.dev3__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.
- pyseekdb/__init__.py +90 -0
- pyseekdb/client/__init__.py +324 -0
- pyseekdb/client/admin_client.py +202 -0
- pyseekdb/client/base_connection.py +82 -0
- pyseekdb/client/client_base.py +1921 -0
- pyseekdb/client/client_oceanbase_server.py +258 -0
- pyseekdb/client/client_seekdb_embedded.py +324 -0
- pyseekdb/client/client_seekdb_server.py +226 -0
- pyseekdb/client/collection.py +485 -0
- pyseekdb/client/database.py +55 -0
- pyseekdb/client/filters.py +357 -0
- pyseekdb/client/meta_info.py +15 -0
- pyseekdb/client/query_result.py +122 -0
- pyseekdb/client/sql_utils.py +48 -0
- pyseekdb/examples/comprehensive_example.py +412 -0
- pyseekdb/examples/simple_example.py +113 -0
- pyseekdb/tests/__init__.py +0 -0
- pyseekdb/tests/test_admin_database_management.py +307 -0
- pyseekdb/tests/test_client_creation.py +425 -0
- pyseekdb/tests/test_collection_dml.py +652 -0
- pyseekdb/tests/test_collection_get.py +550 -0
- pyseekdb/tests/test_collection_hybrid_search.py +1126 -0
- pyseekdb/tests/test_collection_query.py +428 -0
- pyseekdb-0.1.0.dev3.dist-info/LICENSE +202 -0
- pyseekdb-0.1.0.dev3.dist-info/METADATA +856 -0
- pyseekdb-0.1.0.dev3.dist-info/RECORD +27 -0
- pyseekdb-0.1.0.dev3.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AdminClient database management tests - testing all database CRUD operations
|
|
3
|
+
Tests create, get, list, and delete database operations for all three modes
|
|
4
|
+
Supports configuring connection parameters via environment variables
|
|
5
|
+
"""
|
|
6
|
+
import pytest
|
|
7
|
+
import sys
|
|
8
|
+
import os
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
# Add project path
|
|
12
|
+
project_root = Path(__file__).parent.parent.parent
|
|
13
|
+
sys.path.insert(0, str(project_root))
|
|
14
|
+
|
|
15
|
+
import seekdbclient
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# ==================== Environment Variable Configuration ====================
|
|
19
|
+
# Embedded mode
|
|
20
|
+
SEEKDB_PATH = os.environ.get('SEEKDB_PATH', os.path.join(project_root, "seekdb"))
|
|
21
|
+
|
|
22
|
+
# Server mode (SeekDB Server)
|
|
23
|
+
SERVER_HOST = os.environ.get('SERVER_HOST', '127.0.0.1')
|
|
24
|
+
SERVER_PORT = int(os.environ.get('SERVER_PORT', '2881')) # SeekDB Server port
|
|
25
|
+
SERVER_USER = os.environ.get('SERVER_USER', 'root')
|
|
26
|
+
SERVER_PASSWORD = os.environ.get('SERVER_PASSWORD', '')
|
|
27
|
+
|
|
28
|
+
# OceanBase mode
|
|
29
|
+
OB_HOST = os.environ.get('OB_HOST', '127.0.0.1')
|
|
30
|
+
OB_PORT = int(os.environ.get('OB_PORT', '11402'))
|
|
31
|
+
OB_TENANT = os.environ.get('OB_TENANT', 'mysql')
|
|
32
|
+
OB_USER = os.environ.get('OB_USER', 'root')
|
|
33
|
+
OB_PASSWORD = os.environ.get('OB_PASSWORD', '')
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class TestAdminDatabaseManagement:
|
|
37
|
+
"""Test AdminClient database management operations for all three modes"""
|
|
38
|
+
|
|
39
|
+
def test_embedded_admin_database_operations(self):
|
|
40
|
+
"""Test embedded admin client database management: create, get, list, delete"""
|
|
41
|
+
if not os.path.exists(SEEKDB_PATH):
|
|
42
|
+
pytest.fail(
|
|
43
|
+
f"ā SeekDB data directory does not exist: {SEEKDB_PATH}\n\n"
|
|
44
|
+
f"Solution:\n"
|
|
45
|
+
f" 1. Create the directory: mkdir -p {SEEKDB_PATH}\n"
|
|
46
|
+
f" 2. Or set SEEKDB_PATH environment variable to an existing directory:\n"
|
|
47
|
+
f" export SEEKDB_PATH=/path/to/your/seekdb/data\n"
|
|
48
|
+
f" python3 -m pytest seekdbclient/tests/test_admin_database_management.py -v -s"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# Check if seekdb package is available and properly configured
|
|
52
|
+
try:
|
|
53
|
+
import sys
|
|
54
|
+
project_root_str = str(project_root)
|
|
55
|
+
if project_root_str in sys.path:
|
|
56
|
+
sys.path.remove(project_root_str)
|
|
57
|
+
import seekdb
|
|
58
|
+
if not hasattr(seekdb, 'open') and not hasattr(seekdb, '_initialize_module'):
|
|
59
|
+
pytest.fail(
|
|
60
|
+
"ā SeekDB embedded package is not properly installed!\n"
|
|
61
|
+
"The 'seekdb' module exists but lacks required methods.\n"
|
|
62
|
+
"Required: 'open' method or '_initialize_module' method\n\n"
|
|
63
|
+
"Solution: Please install the seekdb embedded package from correct source:\n"
|
|
64
|
+
" pip install seekdb\n"
|
|
65
|
+
"Or contact the seekdb package maintainer for installation guide."
|
|
66
|
+
)
|
|
67
|
+
except ImportError:
|
|
68
|
+
pytest.fail(
|
|
69
|
+
"ā SeekDB embedded package is not installed!\n"
|
|
70
|
+
"The 'seekdb' module cannot be imported.\n\n"
|
|
71
|
+
"Solution: Please install the seekdb embedded package:\n"
|
|
72
|
+
" pip install seekdb\n"
|
|
73
|
+
"Or contact the seekdb package maintainer for installation guide."
|
|
74
|
+
)
|
|
75
|
+
finally:
|
|
76
|
+
if project_root_str not in sys.path:
|
|
77
|
+
sys.path.insert(0, project_root_str)
|
|
78
|
+
|
|
79
|
+
# Create admin client (returns _AdminClientProxy)
|
|
80
|
+
admin = seekdbclient.AdminClient(
|
|
81
|
+
path=SEEKDB_PATH
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Verify admin client type
|
|
85
|
+
assert admin is not None
|
|
86
|
+
assert hasattr(admin, '_server')
|
|
87
|
+
assert isinstance(admin._server, seekdbclient.SeekdbEmbeddedClient)
|
|
88
|
+
|
|
89
|
+
# Test database operations
|
|
90
|
+
test_db_name = "test_embedded_db"
|
|
91
|
+
try:
|
|
92
|
+
print(f"\nā
Embedded admin client created successfully: path={SEEKDB_PATH}")
|
|
93
|
+
|
|
94
|
+
# Step 1: List all databases before test
|
|
95
|
+
print(f"\nš Step 1: List all databases")
|
|
96
|
+
databases_before = admin.list_databases()
|
|
97
|
+
assert databases_before is not None
|
|
98
|
+
assert isinstance(databases_before, (list, tuple))
|
|
99
|
+
print(f" Found {len(databases_before)} databases before test")
|
|
100
|
+
for db in databases_before[:3]:
|
|
101
|
+
print(f" - {db.name} (tenant={db.tenant})")
|
|
102
|
+
|
|
103
|
+
# Step 2: Create new database
|
|
104
|
+
print(f"\nš Step 2: Create database '{test_db_name}'")
|
|
105
|
+
admin.create_database(test_db_name)
|
|
106
|
+
print(f" ā
Database '{test_db_name}' created")
|
|
107
|
+
|
|
108
|
+
# Step 3: Get the created database and verify
|
|
109
|
+
print(f"\nš Step 3: Get database '{test_db_name}' to verify creation")
|
|
110
|
+
db = admin.get_database(test_db_name)
|
|
111
|
+
assert db is not None
|
|
112
|
+
assert db.name == test_db_name
|
|
113
|
+
assert db.tenant is None # Embedded mode has no tenant
|
|
114
|
+
print(f" ā
Database retrieved: {db.name}")
|
|
115
|
+
print(f" - Name: {db.name}")
|
|
116
|
+
print(f" - Tenant: {db.tenant}")
|
|
117
|
+
print(f" - Charset: {db.charset}")
|
|
118
|
+
print(f" - Collation: {db.collation}")
|
|
119
|
+
|
|
120
|
+
# Step 4: Delete the database
|
|
121
|
+
print(f"\nšļø Step 4: Delete database '{test_db_name}'")
|
|
122
|
+
admin.delete_database(test_db_name)
|
|
123
|
+
print(f" ā
Database '{test_db_name}' deleted")
|
|
124
|
+
|
|
125
|
+
# Step 5: List databases again to verify deletion
|
|
126
|
+
print(f"\nš Step 5: List all databases to verify deletion")
|
|
127
|
+
databases_after = admin.list_databases()
|
|
128
|
+
assert databases_after is not None
|
|
129
|
+
print(f" Found {len(databases_after)} databases after deletion")
|
|
130
|
+
# Verify the test database is not in the list
|
|
131
|
+
db_names = [db.name for db in databases_after]
|
|
132
|
+
assert test_db_name not in db_names, f"Database '{test_db_name}' should be deleted"
|
|
133
|
+
print(f" ā
Verified: '{test_db_name}' is not in the database list")
|
|
134
|
+
|
|
135
|
+
print(f"\nš All database management operations completed successfully!")
|
|
136
|
+
|
|
137
|
+
except Exception as e:
|
|
138
|
+
# Cleanup: try to delete test database if it exists
|
|
139
|
+
try:
|
|
140
|
+
admin.delete_database(test_db_name)
|
|
141
|
+
except:
|
|
142
|
+
pass
|
|
143
|
+
pytest.fail(f"Embedded admin client test failed: {e}\n"
|
|
144
|
+
f"Hint: Please ensure SeekDB embedded package is properly installed")
|
|
145
|
+
|
|
146
|
+
def test_server_admin_database_operations(self):
|
|
147
|
+
"""Test server admin client database management: create, get, list, delete"""
|
|
148
|
+
# Create admin client (returns _AdminClientProxy)
|
|
149
|
+
admin = seekdbclient.AdminClient(
|
|
150
|
+
host=SERVER_HOST,
|
|
151
|
+
port=SERVER_PORT,
|
|
152
|
+
user=SERVER_USER,
|
|
153
|
+
password=SERVER_PASSWORD
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
# Verify admin client type
|
|
157
|
+
assert admin is not None
|
|
158
|
+
assert hasattr(admin, '_server')
|
|
159
|
+
assert isinstance(admin._server, seekdbclient.SeekdbServerClient)
|
|
160
|
+
|
|
161
|
+
# Test database operations
|
|
162
|
+
test_db_name = "test_server_db"
|
|
163
|
+
try:
|
|
164
|
+
print(f"\nā
Server admin client created successfully: {SERVER_USER}@{SERVER_HOST}:{SERVER_PORT}")
|
|
165
|
+
|
|
166
|
+
# Step 1: List all databases before test
|
|
167
|
+
print(f"\nš Step 1: List all databases")
|
|
168
|
+
databases_before = admin.list_databases()
|
|
169
|
+
assert databases_before is not None
|
|
170
|
+
assert isinstance(databases_before, (list, tuple))
|
|
171
|
+
print(f" Found {len(databases_before)} databases before test")
|
|
172
|
+
for db in databases_before[:3]:
|
|
173
|
+
print(f" - {db.name} (tenant={db.tenant})")
|
|
174
|
+
|
|
175
|
+
# Step 2: Create new database
|
|
176
|
+
print(f"\nš Step 2: Create database '{test_db_name}'")
|
|
177
|
+
admin.create_database(test_db_name)
|
|
178
|
+
print(f" ā
Database '{test_db_name}' created")
|
|
179
|
+
|
|
180
|
+
# Step 3: Get the created database and verify
|
|
181
|
+
print(f"\nš Step 3: Get database '{test_db_name}' to verify creation")
|
|
182
|
+
db = admin.get_database(test_db_name)
|
|
183
|
+
assert db is not None
|
|
184
|
+
assert db.name == test_db_name
|
|
185
|
+
assert db.tenant is None # Server mode has no tenant
|
|
186
|
+
print(f" ā
Database retrieved: {db.name}")
|
|
187
|
+
print(f" - Name: {db.name}")
|
|
188
|
+
print(f" - Tenant: {db.tenant}")
|
|
189
|
+
print(f" - Charset: {db.charset}")
|
|
190
|
+
print(f" - Collation: {db.collation}")
|
|
191
|
+
|
|
192
|
+
# Step 4: Delete the database
|
|
193
|
+
print(f"\nšļø Step 4: Delete database '{test_db_name}'")
|
|
194
|
+
admin.delete_database(test_db_name)
|
|
195
|
+
print(f" ā
Database '{test_db_name}' deleted")
|
|
196
|
+
|
|
197
|
+
# Step 5: List databases again to verify deletion
|
|
198
|
+
print(f"\nš Step 5: List all databases to verify deletion")
|
|
199
|
+
databases_after = admin.list_databases()
|
|
200
|
+
assert databases_after is not None
|
|
201
|
+
print(f" Found {len(databases_after)} databases after deletion")
|
|
202
|
+
# Verify the test database is not in the list
|
|
203
|
+
db_names = [db.name for db in databases_after]
|
|
204
|
+
assert test_db_name not in db_names, f"Database '{test_db_name}' should be deleted"
|
|
205
|
+
print(f" ā
Verified: '{test_db_name}' is not in the database list")
|
|
206
|
+
|
|
207
|
+
print(f"\nš All database management operations completed successfully!")
|
|
208
|
+
|
|
209
|
+
except Exception as e:
|
|
210
|
+
# Cleanup: try to delete test database if it exists
|
|
211
|
+
try:
|
|
212
|
+
admin.delete_database(test_db_name)
|
|
213
|
+
except:
|
|
214
|
+
pass
|
|
215
|
+
pytest.fail(f"Server admin client test failed ({SERVER_HOST}:{SERVER_PORT}): {e}\n"
|
|
216
|
+
f"Hint: Please ensure SeekDB Server is running on port {SERVER_PORT}")
|
|
217
|
+
|
|
218
|
+
def test_oceanbase_admin_database_operations(self):
|
|
219
|
+
"""Test OceanBase admin client database management: create, get, list, delete"""
|
|
220
|
+
# Create admin client (returns _AdminClientProxy)
|
|
221
|
+
admin = seekdbclient.OBAdminClient(
|
|
222
|
+
host=OB_HOST,
|
|
223
|
+
port=OB_PORT,
|
|
224
|
+
tenant=OB_TENANT,
|
|
225
|
+
user=OB_USER,
|
|
226
|
+
password=OB_PASSWORD
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
# Verify admin client type
|
|
230
|
+
assert admin is not None
|
|
231
|
+
assert hasattr(admin, '_server')
|
|
232
|
+
assert isinstance(admin._server, seekdbclient.OceanBaseServerClient)
|
|
233
|
+
assert admin._server.tenant == OB_TENANT
|
|
234
|
+
|
|
235
|
+
# Test database operations
|
|
236
|
+
test_db_name = "test_oceanbase_db"
|
|
237
|
+
try:
|
|
238
|
+
print(f"\nā
OceanBase admin client created successfully: {OB_USER}@{OB_TENANT}@{OB_HOST}:{OB_PORT}")
|
|
239
|
+
|
|
240
|
+
# Step 1: List all databases before test
|
|
241
|
+
print(f"\nš Step 1: List all databases in tenant '{OB_TENANT}'")
|
|
242
|
+
databases_before = admin.list_databases()
|
|
243
|
+
assert databases_before is not None
|
|
244
|
+
assert isinstance(databases_before, (list, tuple))
|
|
245
|
+
# Verify tenant is set for OceanBase
|
|
246
|
+
for db in databases_before:
|
|
247
|
+
assert db.tenant == OB_TENANT, f"Database {db.name} should have tenant {OB_TENANT}"
|
|
248
|
+
print(f" Found {len(databases_before)} databases before test")
|
|
249
|
+
for db in databases_before[:3]:
|
|
250
|
+
print(f" - {db.name} (tenant={db.tenant})")
|
|
251
|
+
|
|
252
|
+
# Step 2: Create new database
|
|
253
|
+
print(f"\nš Step 2: Create database '{test_db_name}'")
|
|
254
|
+
admin.create_database(test_db_name)
|
|
255
|
+
print(f" ā
Database '{test_db_name}' created in tenant '{OB_TENANT}'")
|
|
256
|
+
|
|
257
|
+
# Step 3: Get the created database and verify
|
|
258
|
+
print(f"\nš Step 3: Get database '{test_db_name}' to verify creation")
|
|
259
|
+
db = admin.get_database(test_db_name)
|
|
260
|
+
assert db is not None
|
|
261
|
+
assert db.name == test_db_name
|
|
262
|
+
assert db.tenant == OB_TENANT # OceanBase mode has tenant
|
|
263
|
+
print(f" ā
Database retrieved: {db.name}")
|
|
264
|
+
print(f" - Name: {db.name}")
|
|
265
|
+
print(f" - Tenant: {db.tenant}")
|
|
266
|
+
print(f" - Charset: {db.charset}")
|
|
267
|
+
print(f" - Collation: {db.collation}")
|
|
268
|
+
|
|
269
|
+
# Step 4: Delete the database
|
|
270
|
+
print(f"\nšļø Step 4: Delete database '{test_db_name}'")
|
|
271
|
+
admin.delete_database(test_db_name)
|
|
272
|
+
print(f" ā
Database '{test_db_name}' deleted from tenant '{OB_TENANT}'")
|
|
273
|
+
|
|
274
|
+
# Step 5: List databases again to verify deletion
|
|
275
|
+
print(f"\nš Step 5: List all databases to verify deletion")
|
|
276
|
+
databases_after = admin.list_databases()
|
|
277
|
+
assert databases_after is not None
|
|
278
|
+
print(f" Found {len(databases_after)} databases after deletion")
|
|
279
|
+
# Verify the test database is not in the list
|
|
280
|
+
db_names = [db.name for db in databases_after]
|
|
281
|
+
assert test_db_name not in db_names, f"Database '{test_db_name}' should be deleted"
|
|
282
|
+
print(f" ā
Verified: '{test_db_name}' is not in the database list")
|
|
283
|
+
|
|
284
|
+
print(f"\nš All database management operations completed successfully!")
|
|
285
|
+
|
|
286
|
+
except Exception as e:
|
|
287
|
+
# Cleanup: try to delete test database if it exists
|
|
288
|
+
try:
|
|
289
|
+
admin.delete_database(test_db_name)
|
|
290
|
+
except:
|
|
291
|
+
pass
|
|
292
|
+
pytest.fail(f"OceanBase admin client test failed ({OB_HOST}:{OB_PORT}): {e}\n"
|
|
293
|
+
f"Hint: Please ensure OceanBase is running and tenant '{OB_TENANT}' is created")
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
if __name__ == "__main__":
|
|
297
|
+
print("\n" + "="*60)
|
|
298
|
+
print("SeekDBClient - AdminClient Database Management Tests")
|
|
299
|
+
print("="*60)
|
|
300
|
+
print(f"\nEnvironment Variable Configuration:")
|
|
301
|
+
print(f" Embedded mode: path={SEEKDB_PATH}")
|
|
302
|
+
print(f" Server mode: {SERVER_USER}@{SERVER_HOST}:{SERVER_PORT}")
|
|
303
|
+
print(f" OceanBase mode: {OB_USER}@{OB_TENANT} -> {OB_HOST}:{OB_PORT}")
|
|
304
|
+
print("="*60 + "\n")
|
|
305
|
+
|
|
306
|
+
pytest.main([__file__, "-v", "-s"])
|
|
307
|
+
|