mindtrace-database 0.2.0__tar.gz → 0.3.0__tar.gz

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 (19) hide show
  1. mindtrace_database-0.3.0/PKG-INFO +622 -0
  2. {mindtrace_database-0.2.0 → mindtrace_database-0.3.0}/mindtrace/database/__init__.py +1 -0
  3. {mindtrace_database-0.2.0 → mindtrace_database-0.3.0}/mindtrace/database/backends/mongo_odm_backend.py +1 -0
  4. {mindtrace_database-0.2.0 → mindtrace_database-0.3.0}/mindtrace/database/backends/redis_odm_backend.py +4 -3
  5. {mindtrace_database-0.2.0 → mindtrace_database-0.3.0}/mindtrace/database/backends/unified_odm_backend.py +1 -0
  6. mindtrace_database-0.3.0/mindtrace_database.egg-info/PKG-INFO +622 -0
  7. {mindtrace_database-0.2.0 → mindtrace_database-0.3.0}/pyproject.toml +2 -1
  8. mindtrace_database-0.2.0/PKG-INFO +0 -17
  9. mindtrace_database-0.2.0/mindtrace_database.egg-info/PKG-INFO +0 -17
  10. {mindtrace_database-0.2.0 → mindtrace_database-0.3.0}/LICENSE +0 -0
  11. {mindtrace_database-0.2.0 → mindtrace_database-0.3.0}/README.md +0 -0
  12. {mindtrace_database-0.2.0 → mindtrace_database-0.3.0}/mindtrace/database/backends/local_odm_backend.py +0 -0
  13. {mindtrace_database-0.2.0 → mindtrace_database-0.3.0}/mindtrace/database/backends/mindtrace_odm_backend.py +0 -0
  14. {mindtrace_database-0.2.0 → mindtrace_database-0.3.0}/mindtrace/database/core/exceptions.py +0 -0
  15. {mindtrace_database-0.2.0 → mindtrace_database-0.3.0}/mindtrace_database.egg-info/SOURCES.txt +0 -0
  16. {mindtrace_database-0.2.0 → mindtrace_database-0.3.0}/mindtrace_database.egg-info/dependency_links.txt +0 -0
  17. {mindtrace_database-0.2.0 → mindtrace_database-0.3.0}/mindtrace_database.egg-info/requires.txt +0 -0
  18. {mindtrace_database-0.2.0 → mindtrace_database-0.3.0}/mindtrace_database.egg-info/top_level.txt +0 -0
  19. {mindtrace_database-0.2.0 → mindtrace_database-0.3.0}/setup.cfg +0 -0
@@ -0,0 +1,622 @@
1
+ Metadata-Version: 2.4
2
+ Name: mindtrace-database
3
+ Version: 0.3.0
4
+ Summary: Database functionality for Mindtrace
5
+ Author: Mindtrace Team
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://mindtrace.ai
8
+ Project-URL: Repository, https://github.com/mindtrace/mindtrace/blob/main/mindtrace/database
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.12
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: beanie<2,>=1.29.0
14
+ Requires-Dist: mindtrace-core
15
+ Requires-Dist: redis>=4.0.0
16
+ Requires-Dist: redis-om>=0.3.5
17
+ Requires-Dist: motor>=3.3.0
18
+ Dynamic: license-file
19
+
20
+ [![PyPI version](https://img.shields.io/pypi/v/mindtrace-database)](https://pypi.org/project/mindtrace-database/)
21
+ [![License](https://img.shields.io/pypi/l/mindtrace-database)](https://github.com/mindtrace/mindtrace/blob/main/mindtrace/database/LICENSE)
22
+
23
+ # Mindtrace Database Module
24
+
25
+ A powerful, flexible Object-Document Mapping (ODM) system that provides a **unified interface** for working with multiple database backends in the Mindtrace project. Write once, run on MongoDB, Redis, or both!
26
+
27
+ ## ✨ Key Features
28
+
29
+ - **Unified Backend System** - One interface for multiple databases
30
+ - **Dynamic Backend Switching** - Switch between MongoDB and Redis at runtime
31
+ - **Simplified Document Models** - Define once, use everywhere
32
+ - **Async/Sync Support** - Choose your preferred programming style
33
+ - **Advanced Querying** - Rich query capabilities across all backends
34
+ - **Comprehensive Error Handling** - Clear, actionable error messages
35
+ - **Full Test Coverage** - Thoroughly tested with unit and integration tests
36
+
37
+ ## Quick Start
38
+
39
+ ### The Simple Way: Unified Documents
40
+
41
+ Define your document model once and use it with any backend:
42
+
43
+ ```python
44
+ from mindtrace.database import UnifiedMindtraceDocument, UnifiedMindtraceODMBackend, BackendType
45
+ from pydantic import Field
46
+
47
+ # 1. Define your document model (works with both MongoDB and Redis!)
48
+ class User(UnifiedMindtraceDocument):
49
+ name: str = Field(description="User's full name")
50
+ age: int = Field(ge=0, description="User's age")
51
+ email: str = Field(description="User's email address")
52
+ skills: list[str] = Field(default_factory=list)
53
+
54
+ class Meta:
55
+ collection_name = "users"
56
+ global_key_prefix = "myapp"
57
+ indexed_fields = ["email", "name"]
58
+ unique_fields = ["email"]
59
+
60
+ # 2. Create backend (supports both MongoDB and Redis)
61
+ backend = UnifiedMindtraceODMBackend(
62
+ unified_model_cls=User,
63
+ mongo_db_uri="mongodb://localhost:27017",
64
+ mongo_db_name="myapp",
65
+ redis_url="redis://localhost:6379",
66
+ preferred_backend=BackendType.MONGO # Start with MongoDB
67
+ )
68
+
69
+ # 3. Initialize
70
+ await backend.initialize_async() # For async operations
71
+ # or
72
+ backend.initialize_sync() # For sync operations
73
+
74
+ # 4. Use it! (Same API regardless of backend)
75
+ user = User(name="Alice", age=30, email="alice@example.com", skills=["Python"])
76
+
77
+ # Insert
78
+ inserted_user = await backend.insert_async(user)
79
+ # or: inserted_user = backend.insert(user)
80
+
81
+ # Get by ID
82
+ retrieved_user = await backend.get_async(inserted_user.id)
83
+
84
+ # Find with filters
85
+ python_users = await backend.find_async({"skills": "Python"})
86
+
87
+ # Switch backends on the fly!
88
+ backend.switch_backend(BackendType.REDIS)
89
+ redis_user = backend.insert(user) # Now using Redis
90
+
91
+ # Get all users
92
+ all_users = await backend.all_async()
93
+ ```
94
+
95
+ ### Traditional Way: Backend-Specific Models
96
+
97
+ If you prefer more control, you can still define backend-specific models:
98
+
99
+ ```python
100
+ from mindtrace.database import (
101
+ MongoMindtraceODMBackend,
102
+ RedisMindtraceODMBackend,
103
+ MindtraceDocument,
104
+ MindtraceRedisDocument
105
+ )
106
+ from beanie import Indexed
107
+ from redis_om import Field as RedisField
108
+ from typing import Annotated
109
+
110
+ # MongoDB model
111
+ class MongoUser(MindtraceDocument):
112
+ name: str
113
+ email: Annotated[str, Indexed(unique=True)]
114
+ age: int
115
+
116
+ class Settings:
117
+ name = "users"
118
+
119
+ # Redis model
120
+ class RedisUser(MindtraceRedisDocument):
121
+ name: str = RedisField(index=True)
122
+ email: str = RedisField(index=True)
123
+ age: int = RedisField(index=True)
124
+
125
+ class Meta:
126
+ global_key_prefix = "myapp"
127
+
128
+ # Use them separately
129
+ mongo_backend = MongoMindtraceODMBackend(
130
+ model_cls=MongoUser,
131
+ db_uri="mongodb://localhost:27017",
132
+ db_name="myapp"
133
+ )
134
+
135
+ redis_backend = RedisMindtraceODMBackend(
136
+ model_cls=RedisUser,
137
+ redis_url="redis://localhost:6379"
138
+ )
139
+ ```
140
+
141
+ ## Available Backends
142
+
143
+ ### 1. UnifiedMindtraceODMBackend (Recommended)
144
+
145
+ The flagship backend that provides a unified interface for multiple databases:
146
+
147
+ **Key Features:**
148
+ - **Single Interface**: One API for all backends
149
+ - **Runtime Switching**: Change backends without code changes
150
+ - **Automatic Model Generation**: Converts unified models to backend-specific formats
151
+ - **Flexible Configuration**: Use one or multiple backends
152
+
153
+ **Configuration Options:**
154
+ ```python
155
+ # Option 1: Unified model (recommended)
156
+ backend = UnifiedMindtraceODMBackend(
157
+ unified_model_cls=MyUnifiedDoc,
158
+ mongo_db_uri="mongodb://localhost:27017",
159
+ mongo_db_name="mydb",
160
+ redis_url="redis://localhost:6379",
161
+ preferred_backend=BackendType.MONGO
162
+ )
163
+
164
+ # Option 2: Separate models
165
+ backend = UnifiedMindtraceODMBackend(
166
+ mongo_model_cls=MyMongoDoc,
167
+ redis_model_cls=MyRedisDoc,
168
+ mongo_db_uri="mongodb://localhost:27017",
169
+ mongo_db_name="mydb",
170
+ redis_url="redis://localhost:6379",
171
+ preferred_backend=BackendType.REDIS
172
+ )
173
+
174
+ # Option 3: Single backend
175
+ backend = UnifiedMindtraceODMBackend(
176
+ unified_model_cls=MyUnifiedDoc,
177
+ mongo_db_uri="mongodb://localhost:27017",
178
+ mongo_db_name="mydb",
179
+ preferred_backend=BackendType.MONGO
180
+ )
181
+ ```
182
+
183
+ ### 2. MongoMindtraceODMBackend
184
+
185
+ Specialized MongoDB backend using Beanie ODM:
186
+
187
+ ```python
188
+ from mindtrace.database import MongoMindtraceODMBackend, MindtraceDocument
189
+
190
+ class User(MindtraceDocument):
191
+ name: str
192
+ email: str
193
+
194
+ class Settings:
195
+ name = "users"
196
+ use_cache = False
197
+
198
+ backend = MongoMindtraceODMBackend(
199
+ model_cls=User,
200
+ db_uri="mongodb://localhost:27017",
201
+ db_name="myapp"
202
+ )
203
+
204
+ # Supports MongoDB-specific features
205
+ pipeline = [{"$match": {"age": {"$gte": 18}}}]
206
+ results = await backend.aggregate(pipeline)
207
+ ```
208
+
209
+ ### 3. RedisMindtraceODMBackend
210
+
211
+ High-performance Redis backend with JSON support:
212
+
213
+ ```python
214
+ from mindtrace.database import RedisMindtraceODMBackend, MindtraceRedisDocument
215
+ from redis_om import Field
216
+
217
+ class User(MindtraceRedisDocument):
218
+ name: str = Field(index=True)
219
+ email: str = Field(index=True)
220
+ age: int = Field(index=True)
221
+
222
+ class Meta:
223
+ global_key_prefix = "myapp"
224
+
225
+ backend = RedisMindtraceODMBackend(
226
+ model_cls=User,
227
+ redis_url="redis://localhost:6379"
228
+ )
229
+
230
+ # Initialize Redis OM
231
+ await backend.initialize()
232
+
233
+ # Supports Redis-specific queries
234
+ users = backend.find(User.age >= 18)
235
+ ```
236
+
237
+ ### 4. LocalMindtraceODMBackend
238
+
239
+ In-memory backend for testing and development:
240
+
241
+ ```python
242
+ from mindtrace.database import LocalMindtraceODMBackend
243
+ from pydantic import BaseModel
244
+
245
+ class User(BaseModel):
246
+ name: str
247
+ email: str
248
+
249
+ backend = LocalMindtraceODMBackend(model_cls=User)
250
+ # No initialization needed - works immediately!
251
+ ```
252
+
253
+ ## API Reference
254
+
255
+ ### Core Operations
256
+
257
+ All backends support these essential operations:
258
+
259
+ ```python
260
+ # Insert a document
261
+ inserted_doc = await backend.insert_async(doc)
262
+ # or: inserted_doc = backend.insert(doc)
263
+
264
+ # Get document by ID
265
+ doc = await backend.get_async("doc_id")
266
+ # or: doc = backend.get("doc_id")
267
+
268
+ # Delete document
269
+ await backend.delete_async("doc_id")
270
+ # or: backend.delete("doc_id")
271
+
272
+ # Get all documents
273
+ all_docs = await backend.all_async()
274
+ # or: all_docs = backend.all()
275
+
276
+ # Find documents with filters
277
+ results = await backend.find_async({"name": "Alice"})
278
+ # or: results = backend.find({"name": "Alice"})
279
+ ```
280
+
281
+ ### Unified Backend Specific
282
+
283
+ Additional methods for the unified backend:
284
+
285
+ ```python
286
+ # Backend management
287
+ backend.switch_backend(BackendType.REDIS)
288
+ current_type = backend.get_current_backend_type()
289
+ is_async = backend.is_async()
290
+
291
+ # Backend availability
292
+ has_mongo = backend.has_mongo_backend()
293
+ has_redis = backend.has_redis_backend()
294
+
295
+ # Direct backend access
296
+ mongo_backend = backend.get_mongo_backend()
297
+ redis_backend = backend.get_redis_backend()
298
+
299
+ # Model access
300
+ raw_model = backend.get_raw_model()
301
+ unified_model = backend.get_unified_model()
302
+ ```
303
+
304
+ ### Advanced Querying
305
+
306
+ #### MongoDB (through Unified Backend)
307
+ ```python
308
+ # MongoDB-style queries
309
+ users = await backend.find_async({"age": {"$gte": 18}})
310
+ users = await backend.find_async({"skills": {"$in": ["Python", "JavaScript"]}})
311
+
312
+ # Aggregation pipelines (when using MongoDB)
313
+ if backend.get_current_backend_type() == BackendType.MONGO:
314
+ pipeline = [
315
+ {"$match": {"age": {"$gte": 18}}},
316
+ {"$group": {"_id": "$department", "count": {"$sum": 1}}}
317
+ ]
318
+ results = await backend.get_mongo_backend().aggregate(pipeline)
319
+ ```
320
+
321
+ #### Redis (through Unified Backend)
322
+ ```python
323
+ # Switch to Redis for these queries
324
+ backend.switch_backend(BackendType.REDIS)
325
+
326
+ # Redis OM expressions
327
+ Model = backend.get_raw_model()
328
+ users = backend.find(Model.age >= 18)
329
+ users = backend.find(Model.name == "Alice")
330
+ users = backend.find(Model.skills << "Python") # Contains
331
+ ```
332
+
333
+ ## Error Handling
334
+
335
+ The module provides comprehensive error handling:
336
+
337
+ ```python
338
+ from mindtrace.database import DocumentNotFoundError, DuplicateInsertError
339
+
340
+ try:
341
+ user = await backend.get_async("non_existent_id")
342
+ except DocumentNotFoundError as e:
343
+ print(f"User not found: {e}")
344
+
345
+ try:
346
+ await backend.insert_async(duplicate_user)
347
+ except DuplicateInsertError as e:
348
+ print(f"User already exists: {e}")
349
+ ```
350
+
351
+ ## Testing
352
+
353
+ The database module includes comprehensive test coverage with both unit and integration tests.
354
+
355
+ ### Test Structure
356
+
357
+ ```
358
+ tests/
359
+ ├── unit/mindtrace/database/ # Unit tests (no DB required)
360
+ │ ├── test_mongo_unit.py
361
+ │ ├── test_redis_unit.py
362
+ │ └── test_unified_unit.py
363
+ └── integration/mindtrace/database/ # Integration tests (DB required)
364
+ ├── test_mongo.py
365
+ ├── test_redis_odm.py
366
+ └── test_unified.py
367
+ ```
368
+
369
+ ### Running Tests
370
+
371
+ #### Quick Start - All Tests
372
+ ```bash
373
+ # Use the test script (handles everything automatically)
374
+ ./scripts/run_tests.sh tests/unit/mindtrace/database tests/integration/mindtrace/database
375
+ ```
376
+
377
+ #### Unit Tests Only (No Database Required)
378
+ ```bash
379
+ # From project root
380
+ PYTHONPATH=mindtrace/core:mindtrace/database:$PYTHONPATH \
381
+ python -m pytest tests/unit/mindtrace/database/ -v
382
+ ```
383
+
384
+ #### Integration Tests (Requires Databases)
385
+ ```bash
386
+ # Start test databases
387
+ docker compose -f tests/docker-compose.yml up -d
388
+
389
+ # Run integration tests
390
+ PYTHONPATH=mindtrace/core:mindtrace/database:$PYTHONPATH \
391
+ python -m pytest tests/integration/mindtrace/database/ -v
392
+
393
+ # Stop test databases
394
+ docker compose -f tests/docker-compose.yml down
395
+ ```
396
+
397
+ #### Targeted Testing
398
+ ```bash
399
+ # Test only unified backend
400
+ ./scripts/run_tests.sh --integration tests/integration/mindtrace/database/test_unified.py
401
+
402
+ # Test only MongoDB
403
+ ./scripts/run_tests.sh --integration tests/integration/mindtrace/database/test_mongo.py
404
+
405
+ # Test only Redis
406
+ ./scripts/run_tests.sh --integration tests/integration/mindtrace/database/test_redis_odm.py
407
+ ```
408
+
409
+ ### Test Coverage
410
+
411
+ The test suite covers:
412
+
413
+ - ✅ **CRUD Operations** - Create, Read, Update, Delete
414
+ - ✅ **Query Operations** - Find, filter, search
415
+ - ✅ **Error Handling** - All exception scenarios
416
+ - ✅ **Backend Switching** - Dynamic backend changes
417
+ - ✅ **Async/Sync Compatibility** - Both programming styles
418
+ - ✅ **Model Conversion** - Unified to backend-specific models
419
+ - ✅ **Edge Cases** - Duplicate keys, missing documents, invalid queries
420
+
421
+ ## Examples
422
+
423
+ ### Complete Example: User Management System
424
+
425
+ ```python
426
+ import asyncio
427
+ from mindtrace.database import (
428
+ UnifiedMindtraceODMBackend,
429
+ UnifiedMindtraceDocument,
430
+ BackendType,
431
+ DocumentNotFoundError
432
+ )
433
+ from pydantic import Field
434
+ from typing import List
435
+
436
+ class User(UnifiedMindtraceDocument):
437
+ name: str = Field(description="Full name")
438
+ email: str = Field(description="Email address")
439
+ age: int = Field(ge=0, le=150, description="Age")
440
+ department: str = Field(description="Department")
441
+ skills: List[str] = Field(default_factory=list)
442
+
443
+ class Meta:
444
+ collection_name = "employees"
445
+ global_key_prefix = "company"
446
+ indexed_fields = ["email", "department", "skills"]
447
+ unique_fields = ["email"]
448
+
449
+ async def main():
450
+ # Setup backend with both MongoDB and Redis
451
+ backend = UnifiedMindtraceODMBackend(
452
+ unified_model_cls=User,
453
+ mongo_db_uri="mongodb://localhost:27017",
454
+ mongo_db_name="company",
455
+ redis_url="redis://localhost:6379",
456
+ preferred_backend=BackendType.MONGO
457
+ )
458
+
459
+ await backend.initialize_async()
460
+
461
+ # Create some users
462
+ users = [
463
+ User(
464
+ name="Alice Johnson",
465
+ email="alice@company.com",
466
+ age=30,
467
+ department="Engineering",
468
+ skills=["Python", "MongoDB", "Docker"]
469
+ ),
470
+ User(
471
+ name="Bob Smith",
472
+ email="bob@company.com",
473
+ age=25,
474
+ department="Engineering",
475
+ skills=["JavaScript", "Redis", "React"]
476
+ ),
477
+ User(
478
+ name="Carol Davis",
479
+ email="carol@company.com",
480
+ age=35,
481
+ department="Marketing",
482
+ skills=["Analytics", "SQL"]
483
+ )
484
+ ]
485
+
486
+ # Insert users
487
+ print("Creating users...")
488
+ for user in users:
489
+ try:
490
+ inserted = await backend.insert_async(user)
491
+ print(f"✅ Created: {inserted.name} (ID: {inserted.id})")
492
+ except Exception as e:
493
+ print(f"❌ Failed to create {user.name}: {e}")
494
+
495
+ # Find engineers
496
+ print("\n🔍 Finding engineers...")
497
+ engineers = await backend.find_async({"department": "Engineering"})
498
+ for eng in engineers:
499
+ print(f"👨‍💻 {eng.name} - Skills: {', '.join(eng.skills)}")
500
+
501
+ # Switch to Redis for fast lookups
502
+ print("\n Switching to Redis for fast operations...")
503
+ backend.switch_backend(BackendType.REDIS)
504
+
505
+ # Insert more users in Redis
506
+ redis_user = User(
507
+ name="Dave Wilson",
508
+ email="dave@company.com",
509
+ age=28,
510
+ department="DevOps",
511
+ skills=["Kubernetes", "Redis", "Monitoring"]
512
+ )
513
+
514
+ redis_inserted = backend.insert(redis_user)
515
+ print(f"Redis user created: {redis_inserted.name}")
516
+
517
+ # Demonstrate backend isolation
518
+ print(f"\n MongoDB users: {len(await backend.get_mongo_backend().all())}")
519
+ print(f"Redis users: {len(backend.get_redis_backend().all())}")
520
+
521
+ # Switch back to MongoDB
522
+ backend.switch_backend(BackendType.MONGO)
523
+ print(f"Back to MongoDB - Users: {len(await backend.all_async())}")
524
+
525
+ if __name__ == "__main__":
526
+ asyncio.run(main())
527
+ ```
528
+
529
+ ### More Examples
530
+
531
+ Check out the `samples/database/` directory for additional examples:
532
+
533
+ - **`using_unified_backend.py`** - Comprehensive unified backend usage
534
+ - **Advanced querying patterns**
535
+ - **Backend switching strategies**
536
+ - **Error handling best practices**
537
+
538
+ ## Best Practices
539
+
540
+ ### 1. Model Design
541
+ ```python
542
+ # ✅ Good: Clear, descriptive models
543
+ class Product(UnifiedMindtraceDocument):
544
+ name: str = Field(description="Product name", min_length=1)
545
+ price: float = Field(ge=0, description="Price in USD")
546
+ category: str = Field(description="Product category")
547
+
548
+ class Meta:
549
+ collection_name = "products"
550
+ indexed_fields = ["category", "name"]
551
+ unique_fields = ["name"]
552
+
553
+ # ❌ Avoid: Unclear models without validation
554
+ class Product(UnifiedMindtraceDocument):
555
+ n: str
556
+ p: float
557
+ c: str
558
+ ```
559
+
560
+ ### 2. Error Handling
561
+ ```python
562
+ # ✅ Always handle database exceptions
563
+ try:
564
+ user = await backend.get_async(user_id)
565
+ print(f"Found user: {user.name}")
566
+ except DocumentNotFoundError:
567
+ print("User not found - creating new user")
568
+ user = await backend.insert_async(User(name="New User", email="new@example.com"))
569
+ except Exception as e:
570
+ logger.error(f"Database error: {e}")
571
+ # Handle appropriately
572
+ ```
573
+
574
+ ### 3. Backend Selection
575
+ ```python
576
+ # ✅ Choose backends based on use case
577
+ if high_frequency_reads:
578
+ backend.switch_backend(BackendType.REDIS) # Fast reads
579
+ else:
580
+ backend.switch_backend(BackendType.MONGO) # Complex queries
581
+ ```
582
+
583
+ ### 4. Initialization
584
+ ```python
585
+ # ✅ Initialize once at application startup
586
+ class DatabaseService:
587
+ def __init__(self):
588
+ self.backend = UnifiedMindtraceODMBackend(...)
589
+
590
+ async def initialize(self):
591
+ await self.backend.initialize_async()
592
+ self.backend.initialize_sync() # If you need both
593
+
594
+ async def cleanup(self):
595
+ # Cleanup if needed
596
+ pass
597
+ ```
598
+
599
+ ## Contributing
600
+
601
+ When adding new features:
602
+
603
+ 1. **Add tests** - Both unit and integration tests
604
+ 2. **Update documentation** - Keep README and docstrings current
605
+ 3. **Follow patterns** - Use existing code style and patterns
606
+ 4. **Test thoroughly** - Run the full test suite
607
+
608
+ ## Requirements
609
+
610
+ - **Python 3.9+**
611
+ - **MongoDB 4.4+** (for MongoDB backend)
612
+ - **Redis 6.0+** (for Redis backend)
613
+ - **Core dependencies**: `pydantic`, `beanie`, `redis-om-python`
614
+
615
+ ## Need Help?
616
+
617
+ - Check the `samples/database/` directory for working examples
618
+ - Look at the test files for usage patterns
619
+ - Review the docstrings in the source code for detailed API documentation
620
+
621
+ The Mindtrace Database Module makes it easy to work with multiple databases through a single, powerful interface. Start simple with the unified backend, then customize as your needs grow!
622
+
@@ -1,4 +1,5 @@
1
1
  from mindtrace.database.backends.local_odm_backend import LocalMindtraceODMBackend
2
+ from mindtrace.database.backends.mindtrace_odm_backend import MindtraceODMBackend
2
3
  from mindtrace.database.backends.mongo_odm_backend import MindtraceDocument, MongoMindtraceODMBackend
3
4
  from mindtrace.database.backends.redis_odm_backend import MindtraceRedisDocument, RedisMindtraceODMBackend
4
5
  from mindtrace.database.backends.unified_odm_backend import (
@@ -86,6 +86,7 @@ class MongoMindtraceODMBackend(MindtraceODMBackend):
86
86
  db_uri (str): MongoDB connection URI string.
87
87
  db_name (str): Name of the MongoDB database to use.
88
88
  """
89
+ super().__init__()
89
90
  self.model_cls = model_cls
90
91
  self.client = AsyncIOMotorClient(db_uri)
91
92
  self.db_name = db_name
@@ -82,6 +82,7 @@ class RedisMindtraceODMBackend(MindtraceODMBackend):
82
82
  model_cls (Type[ModelType]): The document model class to use for operations.
83
83
  redis_url (str): Redis connection URL string.
84
84
  """
85
+ super().__init__()
85
86
  self.model_cls = model_cls
86
87
  self.redis = get_redis_connection(url=redis_url)
87
88
  self._is_initialized = False
@@ -113,7 +114,7 @@ class RedisMindtraceODMBackend(MindtraceODMBackend):
113
114
 
114
115
  self._is_initialized = True
115
116
  except Exception as e:
116
- print(f"Warning: Redis migration failed: {e}")
117
+ self.logger.warning(f"Redis migration failed: {e}")
117
118
  self._is_initialized = True # Continue anyway
118
119
 
119
120
  def is_async(self) -> bool:
@@ -181,7 +182,7 @@ class RedisMindtraceODMBackend(MindtraceODMBackend):
181
182
  raise
182
183
  except Exception:
183
184
  # If all fails, continue without duplicate check but log warning
184
- print(f"Warning: Could not check for duplicates: {e}")
185
+ self.logger.warning(f"Could not check for duplicates: {e}")
185
186
 
186
187
  doc = self.model_cls(**obj_data)
187
188
  doc.save()
@@ -302,7 +303,7 @@ class RedisMindtraceODMBackend(MindtraceODMBackend):
302
303
  return self.model_cls.find().all()
303
304
  except Exception as e:
304
305
  # If query fails, log the error and return empty list
305
- print(f"Warning: Redis query failed: {e}")
306
+ self.logger.warning(f"Redis query failed: {e}")
306
307
  # Try to return all documents if specific query fails
307
308
  try:
308
309
  return self.model_cls.find().all()
@@ -375,6 +375,7 @@ class UnifiedMindtraceODMBackend(MindtraceODMBackend):
375
375
  redis_url: Redis connection URL
376
376
  preferred_backend: Which backend to prefer when both are available
377
377
  """
378
+ super().__init__()
378
379
  self.mongo_backend = None
379
380
  self.redis_backend = None
380
381
  self.preferred_backend = preferred_backend
@@ -0,0 +1,622 @@
1
+ Metadata-Version: 2.4
2
+ Name: mindtrace-database
3
+ Version: 0.3.0
4
+ Summary: Database functionality for Mindtrace
5
+ Author: Mindtrace Team
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://mindtrace.ai
8
+ Project-URL: Repository, https://github.com/mindtrace/mindtrace/blob/main/mindtrace/database
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.12
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: beanie<2,>=1.29.0
14
+ Requires-Dist: mindtrace-core
15
+ Requires-Dist: redis>=4.0.0
16
+ Requires-Dist: redis-om>=0.3.5
17
+ Requires-Dist: motor>=3.3.0
18
+ Dynamic: license-file
19
+
20
+ [![PyPI version](https://img.shields.io/pypi/v/mindtrace-database)](https://pypi.org/project/mindtrace-database/)
21
+ [![License](https://img.shields.io/pypi/l/mindtrace-database)](https://github.com/mindtrace/mindtrace/blob/main/mindtrace/database/LICENSE)
22
+
23
+ # Mindtrace Database Module
24
+
25
+ A powerful, flexible Object-Document Mapping (ODM) system that provides a **unified interface** for working with multiple database backends in the Mindtrace project. Write once, run on MongoDB, Redis, or both!
26
+
27
+ ## ✨ Key Features
28
+
29
+ - **Unified Backend System** - One interface for multiple databases
30
+ - **Dynamic Backend Switching** - Switch between MongoDB and Redis at runtime
31
+ - **Simplified Document Models** - Define once, use everywhere
32
+ - **Async/Sync Support** - Choose your preferred programming style
33
+ - **Advanced Querying** - Rich query capabilities across all backends
34
+ - **Comprehensive Error Handling** - Clear, actionable error messages
35
+ - **Full Test Coverage** - Thoroughly tested with unit and integration tests
36
+
37
+ ## Quick Start
38
+
39
+ ### The Simple Way: Unified Documents
40
+
41
+ Define your document model once and use it with any backend:
42
+
43
+ ```python
44
+ from mindtrace.database import UnifiedMindtraceDocument, UnifiedMindtraceODMBackend, BackendType
45
+ from pydantic import Field
46
+
47
+ # 1. Define your document model (works with both MongoDB and Redis!)
48
+ class User(UnifiedMindtraceDocument):
49
+ name: str = Field(description="User's full name")
50
+ age: int = Field(ge=0, description="User's age")
51
+ email: str = Field(description="User's email address")
52
+ skills: list[str] = Field(default_factory=list)
53
+
54
+ class Meta:
55
+ collection_name = "users"
56
+ global_key_prefix = "myapp"
57
+ indexed_fields = ["email", "name"]
58
+ unique_fields = ["email"]
59
+
60
+ # 2. Create backend (supports both MongoDB and Redis)
61
+ backend = UnifiedMindtraceODMBackend(
62
+ unified_model_cls=User,
63
+ mongo_db_uri="mongodb://localhost:27017",
64
+ mongo_db_name="myapp",
65
+ redis_url="redis://localhost:6379",
66
+ preferred_backend=BackendType.MONGO # Start with MongoDB
67
+ )
68
+
69
+ # 3. Initialize
70
+ await backend.initialize_async() # For async operations
71
+ # or
72
+ backend.initialize_sync() # For sync operations
73
+
74
+ # 4. Use it! (Same API regardless of backend)
75
+ user = User(name="Alice", age=30, email="alice@example.com", skills=["Python"])
76
+
77
+ # Insert
78
+ inserted_user = await backend.insert_async(user)
79
+ # or: inserted_user = backend.insert(user)
80
+
81
+ # Get by ID
82
+ retrieved_user = await backend.get_async(inserted_user.id)
83
+
84
+ # Find with filters
85
+ python_users = await backend.find_async({"skills": "Python"})
86
+
87
+ # Switch backends on the fly!
88
+ backend.switch_backend(BackendType.REDIS)
89
+ redis_user = backend.insert(user) # Now using Redis
90
+
91
+ # Get all users
92
+ all_users = await backend.all_async()
93
+ ```
94
+
95
+ ### Traditional Way: Backend-Specific Models
96
+
97
+ If you prefer more control, you can still define backend-specific models:
98
+
99
+ ```python
100
+ from mindtrace.database import (
101
+ MongoMindtraceODMBackend,
102
+ RedisMindtraceODMBackend,
103
+ MindtraceDocument,
104
+ MindtraceRedisDocument
105
+ )
106
+ from beanie import Indexed
107
+ from redis_om import Field as RedisField
108
+ from typing import Annotated
109
+
110
+ # MongoDB model
111
+ class MongoUser(MindtraceDocument):
112
+ name: str
113
+ email: Annotated[str, Indexed(unique=True)]
114
+ age: int
115
+
116
+ class Settings:
117
+ name = "users"
118
+
119
+ # Redis model
120
+ class RedisUser(MindtraceRedisDocument):
121
+ name: str = RedisField(index=True)
122
+ email: str = RedisField(index=True)
123
+ age: int = RedisField(index=True)
124
+
125
+ class Meta:
126
+ global_key_prefix = "myapp"
127
+
128
+ # Use them separately
129
+ mongo_backend = MongoMindtraceODMBackend(
130
+ model_cls=MongoUser,
131
+ db_uri="mongodb://localhost:27017",
132
+ db_name="myapp"
133
+ )
134
+
135
+ redis_backend = RedisMindtraceODMBackend(
136
+ model_cls=RedisUser,
137
+ redis_url="redis://localhost:6379"
138
+ )
139
+ ```
140
+
141
+ ## Available Backends
142
+
143
+ ### 1. UnifiedMindtraceODMBackend (Recommended)
144
+
145
+ The flagship backend that provides a unified interface for multiple databases:
146
+
147
+ **Key Features:**
148
+ - **Single Interface**: One API for all backends
149
+ - **Runtime Switching**: Change backends without code changes
150
+ - **Automatic Model Generation**: Converts unified models to backend-specific formats
151
+ - **Flexible Configuration**: Use one or multiple backends
152
+
153
+ **Configuration Options:**
154
+ ```python
155
+ # Option 1: Unified model (recommended)
156
+ backend = UnifiedMindtraceODMBackend(
157
+ unified_model_cls=MyUnifiedDoc,
158
+ mongo_db_uri="mongodb://localhost:27017",
159
+ mongo_db_name="mydb",
160
+ redis_url="redis://localhost:6379",
161
+ preferred_backend=BackendType.MONGO
162
+ )
163
+
164
+ # Option 2: Separate models
165
+ backend = UnifiedMindtraceODMBackend(
166
+ mongo_model_cls=MyMongoDoc,
167
+ redis_model_cls=MyRedisDoc,
168
+ mongo_db_uri="mongodb://localhost:27017",
169
+ mongo_db_name="mydb",
170
+ redis_url="redis://localhost:6379",
171
+ preferred_backend=BackendType.REDIS
172
+ )
173
+
174
+ # Option 3: Single backend
175
+ backend = UnifiedMindtraceODMBackend(
176
+ unified_model_cls=MyUnifiedDoc,
177
+ mongo_db_uri="mongodb://localhost:27017",
178
+ mongo_db_name="mydb",
179
+ preferred_backend=BackendType.MONGO
180
+ )
181
+ ```
182
+
183
+ ### 2. MongoMindtraceODMBackend
184
+
185
+ Specialized MongoDB backend using Beanie ODM:
186
+
187
+ ```python
188
+ from mindtrace.database import MongoMindtraceODMBackend, MindtraceDocument
189
+
190
+ class User(MindtraceDocument):
191
+ name: str
192
+ email: str
193
+
194
+ class Settings:
195
+ name = "users"
196
+ use_cache = False
197
+
198
+ backend = MongoMindtraceODMBackend(
199
+ model_cls=User,
200
+ db_uri="mongodb://localhost:27017",
201
+ db_name="myapp"
202
+ )
203
+
204
+ # Supports MongoDB-specific features
205
+ pipeline = [{"$match": {"age": {"$gte": 18}}}]
206
+ results = await backend.aggregate(pipeline)
207
+ ```
208
+
209
+ ### 3. RedisMindtraceODMBackend
210
+
211
+ High-performance Redis backend with JSON support:
212
+
213
+ ```python
214
+ from mindtrace.database import RedisMindtraceODMBackend, MindtraceRedisDocument
215
+ from redis_om import Field
216
+
217
+ class User(MindtraceRedisDocument):
218
+ name: str = Field(index=True)
219
+ email: str = Field(index=True)
220
+ age: int = Field(index=True)
221
+
222
+ class Meta:
223
+ global_key_prefix = "myapp"
224
+
225
+ backend = RedisMindtraceODMBackend(
226
+ model_cls=User,
227
+ redis_url="redis://localhost:6379"
228
+ )
229
+
230
+ # Initialize Redis OM
231
+ await backend.initialize()
232
+
233
+ # Supports Redis-specific queries
234
+ users = backend.find(User.age >= 18)
235
+ ```
236
+
237
+ ### 4. LocalMindtraceODMBackend
238
+
239
+ In-memory backend for testing and development:
240
+
241
+ ```python
242
+ from mindtrace.database import LocalMindtraceODMBackend
243
+ from pydantic import BaseModel
244
+
245
+ class User(BaseModel):
246
+ name: str
247
+ email: str
248
+
249
+ backend = LocalMindtraceODMBackend(model_cls=User)
250
+ # No initialization needed - works immediately!
251
+ ```
252
+
253
+ ## API Reference
254
+
255
+ ### Core Operations
256
+
257
+ All backends support these essential operations:
258
+
259
+ ```python
260
+ # Insert a document
261
+ inserted_doc = await backend.insert_async(doc)
262
+ # or: inserted_doc = backend.insert(doc)
263
+
264
+ # Get document by ID
265
+ doc = await backend.get_async("doc_id")
266
+ # or: doc = backend.get("doc_id")
267
+
268
+ # Delete document
269
+ await backend.delete_async("doc_id")
270
+ # or: backend.delete("doc_id")
271
+
272
+ # Get all documents
273
+ all_docs = await backend.all_async()
274
+ # or: all_docs = backend.all()
275
+
276
+ # Find documents with filters
277
+ results = await backend.find_async({"name": "Alice"})
278
+ # or: results = backend.find({"name": "Alice"})
279
+ ```
280
+
281
+ ### Unified Backend Specific
282
+
283
+ Additional methods for the unified backend:
284
+
285
+ ```python
286
+ # Backend management
287
+ backend.switch_backend(BackendType.REDIS)
288
+ current_type = backend.get_current_backend_type()
289
+ is_async = backend.is_async()
290
+
291
+ # Backend availability
292
+ has_mongo = backend.has_mongo_backend()
293
+ has_redis = backend.has_redis_backend()
294
+
295
+ # Direct backend access
296
+ mongo_backend = backend.get_mongo_backend()
297
+ redis_backend = backend.get_redis_backend()
298
+
299
+ # Model access
300
+ raw_model = backend.get_raw_model()
301
+ unified_model = backend.get_unified_model()
302
+ ```
303
+
304
+ ### Advanced Querying
305
+
306
+ #### MongoDB (through Unified Backend)
307
+ ```python
308
+ # MongoDB-style queries
309
+ users = await backend.find_async({"age": {"$gte": 18}})
310
+ users = await backend.find_async({"skills": {"$in": ["Python", "JavaScript"]}})
311
+
312
+ # Aggregation pipelines (when using MongoDB)
313
+ if backend.get_current_backend_type() == BackendType.MONGO:
314
+ pipeline = [
315
+ {"$match": {"age": {"$gte": 18}}},
316
+ {"$group": {"_id": "$department", "count": {"$sum": 1}}}
317
+ ]
318
+ results = await backend.get_mongo_backend().aggregate(pipeline)
319
+ ```
320
+
321
+ #### Redis (through Unified Backend)
322
+ ```python
323
+ # Switch to Redis for these queries
324
+ backend.switch_backend(BackendType.REDIS)
325
+
326
+ # Redis OM expressions
327
+ Model = backend.get_raw_model()
328
+ users = backend.find(Model.age >= 18)
329
+ users = backend.find(Model.name == "Alice")
330
+ users = backend.find(Model.skills << "Python") # Contains
331
+ ```
332
+
333
+ ## Error Handling
334
+
335
+ The module provides comprehensive error handling:
336
+
337
+ ```python
338
+ from mindtrace.database import DocumentNotFoundError, DuplicateInsertError
339
+
340
+ try:
341
+ user = await backend.get_async("non_existent_id")
342
+ except DocumentNotFoundError as e:
343
+ print(f"User not found: {e}")
344
+
345
+ try:
346
+ await backend.insert_async(duplicate_user)
347
+ except DuplicateInsertError as e:
348
+ print(f"User already exists: {e}")
349
+ ```
350
+
351
+ ## Testing
352
+
353
+ The database module includes comprehensive test coverage with both unit and integration tests.
354
+
355
+ ### Test Structure
356
+
357
+ ```
358
+ tests/
359
+ ├── unit/mindtrace/database/ # Unit tests (no DB required)
360
+ │ ├── test_mongo_unit.py
361
+ │ ├── test_redis_unit.py
362
+ │ └── test_unified_unit.py
363
+ └── integration/mindtrace/database/ # Integration tests (DB required)
364
+ ├── test_mongo.py
365
+ ├── test_redis_odm.py
366
+ └── test_unified.py
367
+ ```
368
+
369
+ ### Running Tests
370
+
371
+ #### Quick Start - All Tests
372
+ ```bash
373
+ # Use the test script (handles everything automatically)
374
+ ./scripts/run_tests.sh tests/unit/mindtrace/database tests/integration/mindtrace/database
375
+ ```
376
+
377
+ #### Unit Tests Only (No Database Required)
378
+ ```bash
379
+ # From project root
380
+ PYTHONPATH=mindtrace/core:mindtrace/database:$PYTHONPATH \
381
+ python -m pytest tests/unit/mindtrace/database/ -v
382
+ ```
383
+
384
+ #### Integration Tests (Requires Databases)
385
+ ```bash
386
+ # Start test databases
387
+ docker compose -f tests/docker-compose.yml up -d
388
+
389
+ # Run integration tests
390
+ PYTHONPATH=mindtrace/core:mindtrace/database:$PYTHONPATH \
391
+ python -m pytest tests/integration/mindtrace/database/ -v
392
+
393
+ # Stop test databases
394
+ docker compose -f tests/docker-compose.yml down
395
+ ```
396
+
397
+ #### Targeted Testing
398
+ ```bash
399
+ # Test only unified backend
400
+ ./scripts/run_tests.sh --integration tests/integration/mindtrace/database/test_unified.py
401
+
402
+ # Test only MongoDB
403
+ ./scripts/run_tests.sh --integration tests/integration/mindtrace/database/test_mongo.py
404
+
405
+ # Test only Redis
406
+ ./scripts/run_tests.sh --integration tests/integration/mindtrace/database/test_redis_odm.py
407
+ ```
408
+
409
+ ### Test Coverage
410
+
411
+ The test suite covers:
412
+
413
+ - ✅ **CRUD Operations** - Create, Read, Update, Delete
414
+ - ✅ **Query Operations** - Find, filter, search
415
+ - ✅ **Error Handling** - All exception scenarios
416
+ - ✅ **Backend Switching** - Dynamic backend changes
417
+ - ✅ **Async/Sync Compatibility** - Both programming styles
418
+ - ✅ **Model Conversion** - Unified to backend-specific models
419
+ - ✅ **Edge Cases** - Duplicate keys, missing documents, invalid queries
420
+
421
+ ## Examples
422
+
423
+ ### Complete Example: User Management System
424
+
425
+ ```python
426
+ import asyncio
427
+ from mindtrace.database import (
428
+ UnifiedMindtraceODMBackend,
429
+ UnifiedMindtraceDocument,
430
+ BackendType,
431
+ DocumentNotFoundError
432
+ )
433
+ from pydantic import Field
434
+ from typing import List
435
+
436
+ class User(UnifiedMindtraceDocument):
437
+ name: str = Field(description="Full name")
438
+ email: str = Field(description="Email address")
439
+ age: int = Field(ge=0, le=150, description="Age")
440
+ department: str = Field(description="Department")
441
+ skills: List[str] = Field(default_factory=list)
442
+
443
+ class Meta:
444
+ collection_name = "employees"
445
+ global_key_prefix = "company"
446
+ indexed_fields = ["email", "department", "skills"]
447
+ unique_fields = ["email"]
448
+
449
+ async def main():
450
+ # Setup backend with both MongoDB and Redis
451
+ backend = UnifiedMindtraceODMBackend(
452
+ unified_model_cls=User,
453
+ mongo_db_uri="mongodb://localhost:27017",
454
+ mongo_db_name="company",
455
+ redis_url="redis://localhost:6379",
456
+ preferred_backend=BackendType.MONGO
457
+ )
458
+
459
+ await backend.initialize_async()
460
+
461
+ # Create some users
462
+ users = [
463
+ User(
464
+ name="Alice Johnson",
465
+ email="alice@company.com",
466
+ age=30,
467
+ department="Engineering",
468
+ skills=["Python", "MongoDB", "Docker"]
469
+ ),
470
+ User(
471
+ name="Bob Smith",
472
+ email="bob@company.com",
473
+ age=25,
474
+ department="Engineering",
475
+ skills=["JavaScript", "Redis", "React"]
476
+ ),
477
+ User(
478
+ name="Carol Davis",
479
+ email="carol@company.com",
480
+ age=35,
481
+ department="Marketing",
482
+ skills=["Analytics", "SQL"]
483
+ )
484
+ ]
485
+
486
+ # Insert users
487
+ print("Creating users...")
488
+ for user in users:
489
+ try:
490
+ inserted = await backend.insert_async(user)
491
+ print(f"✅ Created: {inserted.name} (ID: {inserted.id})")
492
+ except Exception as e:
493
+ print(f"❌ Failed to create {user.name}: {e}")
494
+
495
+ # Find engineers
496
+ print("\n🔍 Finding engineers...")
497
+ engineers = await backend.find_async({"department": "Engineering"})
498
+ for eng in engineers:
499
+ print(f"👨‍💻 {eng.name} - Skills: {', '.join(eng.skills)}")
500
+
501
+ # Switch to Redis for fast lookups
502
+ print("\n Switching to Redis for fast operations...")
503
+ backend.switch_backend(BackendType.REDIS)
504
+
505
+ # Insert more users in Redis
506
+ redis_user = User(
507
+ name="Dave Wilson",
508
+ email="dave@company.com",
509
+ age=28,
510
+ department="DevOps",
511
+ skills=["Kubernetes", "Redis", "Monitoring"]
512
+ )
513
+
514
+ redis_inserted = backend.insert(redis_user)
515
+ print(f"Redis user created: {redis_inserted.name}")
516
+
517
+ # Demonstrate backend isolation
518
+ print(f"\n MongoDB users: {len(await backend.get_mongo_backend().all())}")
519
+ print(f"Redis users: {len(backend.get_redis_backend().all())}")
520
+
521
+ # Switch back to MongoDB
522
+ backend.switch_backend(BackendType.MONGO)
523
+ print(f"Back to MongoDB - Users: {len(await backend.all_async())}")
524
+
525
+ if __name__ == "__main__":
526
+ asyncio.run(main())
527
+ ```
528
+
529
+ ### More Examples
530
+
531
+ Check out the `samples/database/` directory for additional examples:
532
+
533
+ - **`using_unified_backend.py`** - Comprehensive unified backend usage
534
+ - **Advanced querying patterns**
535
+ - **Backend switching strategies**
536
+ - **Error handling best practices**
537
+
538
+ ## Best Practices
539
+
540
+ ### 1. Model Design
541
+ ```python
542
+ # ✅ Good: Clear, descriptive models
543
+ class Product(UnifiedMindtraceDocument):
544
+ name: str = Field(description="Product name", min_length=1)
545
+ price: float = Field(ge=0, description="Price in USD")
546
+ category: str = Field(description="Product category")
547
+
548
+ class Meta:
549
+ collection_name = "products"
550
+ indexed_fields = ["category", "name"]
551
+ unique_fields = ["name"]
552
+
553
+ # ❌ Avoid: Unclear models without validation
554
+ class Product(UnifiedMindtraceDocument):
555
+ n: str
556
+ p: float
557
+ c: str
558
+ ```
559
+
560
+ ### 2. Error Handling
561
+ ```python
562
+ # ✅ Always handle database exceptions
563
+ try:
564
+ user = await backend.get_async(user_id)
565
+ print(f"Found user: {user.name}")
566
+ except DocumentNotFoundError:
567
+ print("User not found - creating new user")
568
+ user = await backend.insert_async(User(name="New User", email="new@example.com"))
569
+ except Exception as e:
570
+ logger.error(f"Database error: {e}")
571
+ # Handle appropriately
572
+ ```
573
+
574
+ ### 3. Backend Selection
575
+ ```python
576
+ # ✅ Choose backends based on use case
577
+ if high_frequency_reads:
578
+ backend.switch_backend(BackendType.REDIS) # Fast reads
579
+ else:
580
+ backend.switch_backend(BackendType.MONGO) # Complex queries
581
+ ```
582
+
583
+ ### 4. Initialization
584
+ ```python
585
+ # ✅ Initialize once at application startup
586
+ class DatabaseService:
587
+ def __init__(self):
588
+ self.backend = UnifiedMindtraceODMBackend(...)
589
+
590
+ async def initialize(self):
591
+ await self.backend.initialize_async()
592
+ self.backend.initialize_sync() # If you need both
593
+
594
+ async def cleanup(self):
595
+ # Cleanup if needed
596
+ pass
597
+ ```
598
+
599
+ ## Contributing
600
+
601
+ When adding new features:
602
+
603
+ 1. **Add tests** - Both unit and integration tests
604
+ 2. **Update documentation** - Keep README and docstrings current
605
+ 3. **Follow patterns** - Use existing code style and patterns
606
+ 4. **Test thoroughly** - Run the full test suite
607
+
608
+ ## Requirements
609
+
610
+ - **Python 3.9+**
611
+ - **MongoDB 4.4+** (for MongoDB backend)
612
+ - **Redis 6.0+** (for Redis backend)
613
+ - **Core dependencies**: `pydantic`, `beanie`, `redis-om-python`
614
+
615
+ ## Need Help?
616
+
617
+ - Check the `samples/database/` directory for working examples
618
+ - Look at the test files for usage patterns
619
+ - Review the docstrings in the source code for detailed API documentation
620
+
621
+ The Mindtrace Database Module makes it easy to work with multiple databases through a single, powerful interface. Start simple with the unified backend, then customize as your needs grow!
622
+
@@ -1,7 +1,8 @@
1
1
  [project]
2
2
  name = "mindtrace-database"
3
- version = "0.2.0"
3
+ version = "0.3.0"
4
4
  description = "Database functionality for Mindtrace"
5
+ readme = "README.md"
5
6
  license = "Apache-2.0"
6
7
  authors = [
7
8
  {name = "Mindtrace Team"}
@@ -1,17 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: mindtrace-database
3
- Version: 0.2.0
4
- Summary: Database functionality for Mindtrace
5
- Author: Mindtrace Team
6
- License-Expression: Apache-2.0
7
- Project-URL: Homepage, https://mindtrace.ai
8
- Project-URL: Repository, https://github.com/mindtrace/mindtrace/blob/main/mindtrace/database
9
- Classifier: Programming Language :: Python :: 3
10
- Classifier: Programming Language :: Python :: 3.12
11
- License-File: LICENSE
12
- Requires-Dist: beanie<2,>=1.29.0
13
- Requires-Dist: mindtrace-core
14
- Requires-Dist: redis>=4.0.0
15
- Requires-Dist: redis-om>=0.3.5
16
- Requires-Dist: motor>=3.3.0
17
- Dynamic: license-file
@@ -1,17 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: mindtrace-database
3
- Version: 0.2.0
4
- Summary: Database functionality for Mindtrace
5
- Author: Mindtrace Team
6
- License-Expression: Apache-2.0
7
- Project-URL: Homepage, https://mindtrace.ai
8
- Project-URL: Repository, https://github.com/mindtrace/mindtrace/blob/main/mindtrace/database
9
- Classifier: Programming Language :: Python :: 3
10
- Classifier: Programming Language :: Python :: 3.12
11
- License-File: LICENSE
12
- Requires-Dist: beanie<2,>=1.29.0
13
- Requires-Dist: mindtrace-core
14
- Requires-Dist: redis>=4.0.0
15
- Requires-Dist: redis-om>=0.3.5
16
- Requires-Dist: motor>=3.3.0
17
- Dynamic: license-file