{"id":24760735,"url":"https://github.com/tuanle96/earnorm","last_synced_at":"2025-06-11T13:10:47.272Z","repository":{"id":272134380,"uuid":"915610222","full_name":"tuanle96/earnorm","owner":"tuanle96","description":"EarnORM is a high-performance, async-first MongoDB ORM for Python, designed to maximize throughput in I/O-bound applications. Built on top of Motor and Pydantic, it leverages the full power of async/await to handle thousands of database operations concurrently while maintaining type safety and data validation.","archived":false,"fork":false,"pushed_at":"2025-01-24T11:06:13.000Z","size":6728,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"prototype","last_synced_at":"2025-01-24T12:19:40.149Z","etag":null,"topics":["asyncio","hacktoberfest","mongo","mongodb","mongodb-orm","motor","nosql","orm","pydantic","python"],"latest_commit_sha":null,"homepage":"https://earnorm.dev","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tuanle96.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["tuanle96"],"patreon":"earnorm","open_collective":"earnorm","ko_fi":"earnorm","liberapay":"earnorm","issuehunt":"earnorm","custom":["https://earnorm.dev/sponsor"]}},"created_at":"2025-01-12T10:33:35.000Z","updated_at":"2025-01-24T11:06:17.000Z","dependencies_parsed_at":null,"dependency_job_id":"39f801ed-3b5c-4555-b066-4c90e1a3001b","html_url":"https://github.com/tuanle96/earnorm","commit_stats":null,"previous_names":["tuanle96/earnorm"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tuanle96%2Fearnorm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tuanle96%2Fearnorm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tuanle96%2Fearnorm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tuanle96%2Fearnorm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tuanle96","download_url":"https://codeload.github.com/tuanle96/earnorm/tar.gz/refs/heads/prototype","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":236063503,"owners_count":19088988,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asyncio","hacktoberfest","mongo","mongodb","mongodb-orm","motor","nosql","orm","pydantic","python"],"created_at":"2025-01-28T18:19:00.214Z","updated_at":"2025-01-28T18:19:00.845Z","avatar_url":"https://github.com/tuanle96.png","language":"Python","funding_links":["https://github.com/sponsors/tuanle96","https://patreon.com/earnorm","https://opencollective.com/earnorm","https://ko-fi.com/earnorm","https://liberapay.com/earnorm","https://issuehunt.io/r/earnorm","https://earnorm.dev/sponsor"],"categories":[],"sub_categories":[],"readme":"# EarnORM\n\n[![Project Status: Prototype](https://img.shields.io/badge/Project%20Status-Prototype-yellow.svg)]()\n[![License: CC BY-NC](https://img.shields.io/badge/License-CC%20BY--NC-lightgrey.svg)]()\n[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)]()\n[![PyPI version](https://badge.fury.io/py/earnorm.svg)](https://badge.fury.io/py/earnorm)\n\nEarnORM is a high-performance, async-first MongoDB ORM for Python, designed to maximize throughput in I/O-bound applications. Built on top of Motor and Pydantic, it leverages the full power of async/await to handle thousands of database operations concurrently while maintaining type safety and data validation.\n\n## 🌟 Key Highlights\n\n- **Async-First Architecture**: Built from ground up with async/await for maximum I/O performance\n- **Type Safety \u0026 Validation**: Full type hints and runtime validation powered by Pydantic\n- **Powerful Query System**: Flexible domain expressions and advanced filtering capabilities\n- **Relationship Management**: Comprehensive support for one-to-one, one-to-many, and many-to-many relationships\n- **Developer Experience**: Rich set of tools, clear documentation, and extensive examples\n\n## 🚀 Features\n\n### Core Features\n- **Model System**\n  - Type-safe model definitions with Pydantic integration\n  - Automatic schema validation and type conversion\n  - Flexible field types with custom validation\n  - Built-in support for indexes and constraints\n\n- **Query System**\n  - Powerful domain expressions for complex queries\n  - Fluent interface for query building\n  - Advanced filtering and sorting capabilities\n  - Efficient batch operations support\n\n- **Relationship Management**\n  - One-to-one, one-to-many, many-to-many relationships\n  - Lazy and eager loading strategies\n  - Cascade operations support\n  - Bidirectional relationship handling\n\n### Performance Features\n- **Connection Management**\n  - Smart connection pooling with Motor\n  - Automatic connection health monitoring\n  - Pool metrics and diagnostics\n  - Connection lifecycle management\n\n- **Query Optimization**\n  - Automatic index management\n  - Query plan optimization\n  - Efficient batch operations\n  - Memory usage optimization\n\n### Developer Tools\n- **Documentation**\n  - Comprehensive API documentation\n  - Best practices guides\n  - Code examples and tutorials\n  - Integration examples with popular frameworks\n\n- **Development Support**\n  - Full IDE support with type hints\n  - Clear error messages and validation\n  - Debugging and logging utilities\n  - Testing utilities and fixtures\n\n## 🔄 Feature Comparison\n\nBelow is a detailed comparison between EarnORM and other popular MongoDB ODMs for Python:\n\n| Feature                     | EarnORM | MongoEngine | Beanie | ODMantic | Motor |\n|----------------------------|---------|-------------|---------|-----------|-------|\n| **Core Features**          |         |             |         |           |       |\n| Async Support              | ✅      | ❌         | ✅      | ✅        | ✅    |\n| Type Safety                | ✅      | ⚠️         | ✅      | ✅        | ❌    |\n| Type Hints                 | ✅      | ⚠️         | ✅      | ✅        | ❌    |\n| Pydantic Integration       | ✅      | ❌         | ✅      | ✅        | ❌    |\n| Field Validation           | ✅      | ✅         | ✅      | ✅        | ❌    |\n| Custom Validators          | ✅      | ✅         | ✅      | ✅        | ❌    |\n| Default Values             | ✅      | ✅         | ✅      | ✅        | ❌    |\n| **Query Features**         |         |             |         |           |       |\n| Query Builder              | ✅      | ✅         | ✅      | ✅        | ⚠️    |\n| Complex Queries            | ✅      | ✅         | ✅      | ✅        | ⚠️    |\n| Aggregation Pipeline       | ✅      | ✅         | ✅      | ⚠️        | ✅    |\n| Text Search                | ✅      | ✅         | ✅      | ⚠️        | ✅    |\n| Geospatial Queries        | ✅      | ✅         | ✅      | ⚠️        | ✅    |\n| **Database Features**      |         |             |         |           |       |\n| Connection Pooling         | ✅      | ✅         | ✅      | ✅        | ✅    |\n| Multiple Databases         | ✅      | ✅         | ✅      | ✅        | ✅    |\n| GridFS Support             | ✅      | ✅         | ⚠️      | ❌        | ✅    |\n| Transactions               | ✅      | ⚠️         | ✅      | ✅        | ✅    |\n| Change Streams             | ✅      | ❌         | ✅      | ❌        | ✅    |\n| **Relationship Features**  |         |             |         |           |       |\n| One-to-One                | ✅      | ✅         | ✅      | ✅        | ❌    |\n| One-to-Many               | ✅      | ✅         | ✅      | ✅        | ❌    |\n| Many-to-Many              | ✅      | ✅         | ✅      | ✅        | ❌    |\n| Lazy Loading              | ✅      | ✅         | ✅      | ✅        | ❌    |\n| Cascade Operations        | ✅      | ⚠️         | ⚠️      | ⚠️        | ❌    |\n| **Enterprise Features**    |         |             |         |           |       |\n| Caching                   | ✅      | ❌         | ⚠️      | ❌        | ❌    |\n| Event System              | ✅      | ⚠️         | ⚠️      | ❌        | ❌    |\n| Lifecycle Hooks           | ✅      | ✅         | ✅      | ⚠️        | ❌    |\n| Migration Support         | ✅      | ❌         | ⚠️      | ❌        | ❌    |\n| Schema Evolution          | ✅      | ❌         | ⚠️      | ❌        | ❌    |\n| **Developer Experience**   |         |             |         |           |       |\n| IDE Support               | ✅      | ⚠️         | ✅      | ✅        | ⚠️    |\n| Documentation             | ✅      | ✅         | ✅      | ✅        | ✅    |\n| Code Examples             | ✅      | ✅         | ✅      | ✅        | ✅    |\n| Testing Support           | ✅      | ✅         | ✅      | ✅        | ⚠️    |\n| Community Support         | ⚠️      | ✅         | ✅      | ✅        | ✅    |\n\nLegend:\n- ✅ Full support\n- ⚠️ Basic/Partial support\n- ❌ Not supported\n\n**Notes:**\n1. **Async Support**: EarnORM is built with async-first approach, while MongoEngine is sync-only\n2. **Type Safety**: EarnORM and Beanie provide full type hints and runtime type checking\n3. **GridFS**: EarnORM offers comprehensive GridFS support with streaming and metadata management\n4. **Relationships**: EarnORM provides full relationship support with lazy loading and cascade operations\n5. **Enterprise Features**: EarnORM includes advanced features like caching, events, and schema evolution\n6. **Developer Experience**: All ODMs provide good documentation, but IDE support varies\n\nChoose EarnORM if you need:\n- Async-first development\n- Strong type safety\n- Advanced relationship features\n- Enterprise-grade features\n- Comprehensive GridFS support\n- Modern Python development experience\n\n## 🏗 Project Status\n\n### ✅ Implemented\n- **Core Features**\n  - Async model system with Motor integration\n  - Field types and validation\n  - Basic relationship support\n  - Domain expressions for querying\n  - Collection and index management\n\n- **Performance Features**\n  - Connection pooling\n  - Basic query optimization\n  - Batch operations\n  - Memory management\n\n### 🚧 In Development\n- **Core Features**\n  - Advanced relationship features\n  - Complex query optimization\n  - Schema migration tools\n  - Event system enhancements\n\n- **Developer Tools**\n  - CLI tools for common tasks\n  - Additional testing utilities\n  - Documentation improvements\n  - More framework integration examples\n\n## 📝 Documentation\n\n### Getting Started\n- [Installation Guide](https://earnorm.readthedocs.io/installation)\n- [Quick Start Tutorial](https://earnorm.readthedocs.io/quickstart)\n- [Basic Concepts](https://earnorm.readthedocs.io/concepts)\n\n### Core Documentation\n- [Model System](https://earnorm.readthedocs.io/models)\n- [Query System](https://earnorm.readthedocs.io/queries)\n- [Relationships](https://earnorm.readthedocs.io/relationships)\n- [Field Types](https://earnorm.readthedocs.io/fields)\n\n### Advanced Topics\n- [Performance Optimization](https://earnorm.readthedocs.io/performance)\n- [Connection Management](https://earnorm.readthedocs.io/connections)\n- [Best Practices](https://earnorm.readthedocs.io/best-practices)\n\n## 💡 Examples\n\n### Basic Usage\n```python\nimport asyncio\nfrom earnorm import init, Model, fields\n\nasync def main():\n    # Initialize EarnORM\n    await init(\n        mongo_uri=\"mongodb://localhost:27017\",\n        database=\"example\"\n    )\n\n    class User(Model):\n        _collection = \"users\"\n        \n        name = fields.String(required=True)\n        email = fields.Email(required=True, unique=True)\n        age = fields.Integer(required=True)\n\n    # Create user\n    user = await User.create({\n        \"name\": \"John\",\n        \"email\": \"john@example.com\",\n        \"age\": 25\n    })\n\n    # Query users\n    adult_users = await User.search([\n        (\"age\", \"\u003e=\", 18),\n        (\"status\", \"=\", \"active\")\n    ])\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n### Relationship Example\n```python\nclass User(Model):\n    _collection = \"users\"\n    \n    name = fields.String(required=True)\n    posts = relationships.OneToMany(\"Post\", \"author_id\")\n\nclass Post(Model):\n    _collection = \"posts\"\n    \n    title = fields.String(required=True)\n    author = relationships.ManyToOne(\"User\", \"author_id\")\n\n# Query related records\nuser = await User.get(user_id)\nuser_posts = await user.posts.filter(status=\"published\").all()\n```\n\n### Advanced Query Example\n```python\nfrom earnorm.domain import DomainBuilder\n\n# Build complex query\ndomain = (\n    DomainBuilder()\n    .field(\"age\").greater_than(18)\n    .and_()\n    .open_group()\n        .field(\"role\").in_([\"admin\", \"manager\"])\n        .or_()\n        .field(\"status\").equals(\"active\")\n    .close_group()\n    .build()\n)\n\n# Execute query\nusers = await User.search(domain)\n```\n\n[See more examples in our documentation](https://earnorm.readthedocs.io/examples)\n\n## 🤝 Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.\n\n## 📄 License\n\nEarnORM is released under the Creative Commons Attribution-NonCommercial (CC BY-NC) license.\n\n## 📧 Contact\n\n- Email: [contact@earnorm.dev](mailto:contact@earnorm.dev)\n- GitHub Issues: [earnorm/issues](https://github.com/earnorm/earnorm/issues)\n\n## ⭐️ Credits\n\nEarnORM is developed by the EarnBase team and the open source community.\n\n## Connection Pool Module\n\n### Progress\n\n#### Completed\n- Protocol layer implementation (database, connection, operations)\n- Error handling and custom exceptions\n- MongoDB pool implementation with retry and circuit breaker\n- Redis pool implementation with retry and circuit breaker\n- Retry mechanism with exponential backoff\n- Circuit breaker implementation\n- Integration of retry and circuit breaker into pools\n- Basic MySQL \u0026 PostgreSQL implementations with NotImplementedError\n- Factory and Registry integration\n- Cleanup of unused files (context.py)\n\n#### In Progress\n- Type hints fixes and improvements\n- Documentation updates\n- Testing setup\n\n#### Pending (Future)\n- Monitoring and metrics\n- Redis pub/sub support\n- Performance optimization\n- Full MySQL \u0026 PostgreSQL implementations\n- CI/CD pipeline setup\n\n### Known Issues\n1. Type hints:\n   - Type variables `DB` and `COLL` need better definition\n   - Method overrides have incompatible return types\n   - MongoDB and Redis driver types need completion\n   - Dictionary key type mismatch in pool implementations\n\n2. Code Quality:\n   - Unused imports in protocol files\n   - Decorator type hints need improvement\n   - Some methods lack proper error handling\n\n### Next Steps\n1. **Immediate Tasks**:\n   - Fix type hints and linter errors\n   - Complete documentation with new examples\n   - Set up testing framework\n\n2. **Future Tasks**:\n   - Implement monitoring and metrics\n   - Add Redis pub/sub support\n   - Optimize performance\n   - Implement full MySQL \u0026 PostgreSQL support\n   - Set up CI/CD pipeline\n\n### Usage Examples\n\n```python\n# Using Factory Pattern\nfrom earnorm.pool.factory import PoolFactory\n\n# Create MongoDB Pool\nmongo_pool = PoolFactory.create(\n    \"mongodb\",\n    uri=\"mongodb://localhost:27017\",\n    database=\"test\",\n    min_size=1,\n    max_size=10,\n    retry_policy=RetryPolicy(\n        max_retries=3,\n        base_delay=1.0,\n        max_delay=5.0,\n    ),\n    circuit_breaker=CircuitBreaker(\n        failure_threshold=5,\n        reset_timeout=30.0,\n        half_open_timeout=5.0,\n    ),\n)\n\n# Create Redis Pool\nredis_pool = PoolFactory.create(\n    \"redis\",\n    uri=\"redis://localhost:6379\",\n    min_size=1,\n    max_size=10,\n    retry_policy=RetryPolicy(\n        max_retries=3,\n        base_delay=1.0,\n        max_delay=5.0,\n    ),\n    circuit_breaker=CircuitBreaker(\n        failure_threshold=5,\n        reset_timeout=30.0,\n        half_open_timeout=5.0,\n    ),\n)\n\n# Using Registry Pattern\nfrom earnorm.pool.registry import PoolRegistry\n\n# Register custom pool implementation\nPoolRegistry.register(\"custom\", CustomPool)\n\n# Get pool class\npool_class = PoolRegistry.get(\"mongodb\")\npool = pool_class(uri=\"mongodb://localhost:27017\")\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftuanle96%2Fearnorm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftuanle96%2Fearnorm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftuanle96%2Fearnorm/lists"}