{"id":15061284,"url":"https://github.com/dellius-alexander/crudrepository","last_synced_at":"2026-01-24T07:32:35.851Z","repository":{"id":232942465,"uuid":"785605385","full_name":"dellius-alexander/CRUDRepository","owner":"dellius-alexander","description":"The CRUDRepository is a Python project designed to provide a generic implementation of Create, Read, Update, and Delete (CRUD) operations for various databases. It uses the concept of repositories to abstract the data access layer, allowing for easy switching between different databases.","archived":false,"fork":false,"pushed_at":"2024-08-13T07:10:00.000Z","size":169,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-16T07:16:37.848Z","etag":null,"topics":["crud-operation","database","mariadb-database","mysql-database","postgresql-database","sqlalchemy"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dellius-alexander.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"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}},"created_at":"2024-04-12T08:23:46.000Z","updated_at":"2024-06-18T00:36:24.000Z","dependencies_parsed_at":"2024-08-12T22:39:16.991Z","dependency_job_id":null,"html_url":"https://github.com/dellius-alexander/CRUDRepository","commit_stats":null,"previous_names":["dellius-alexander/crudrepository"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dellius-alexander%2FCRUDRepository","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dellius-alexander%2FCRUDRepository/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dellius-alexander%2FCRUDRepository/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dellius-alexander%2FCRUDRepository/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dellius-alexander","download_url":"https://codeload.github.com/dellius-alexander/CRUDRepository/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239194343,"owners_count":19598018,"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":["crud-operation","database","mariadb-database","mysql-database","postgresql-database","sqlalchemy"],"created_at":"2024-09-24T23:17:41.605Z","updated_at":"2025-10-31T12:30:22.887Z","avatar_url":"https://github.com/dellius-alexander.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build test and deploy to package repository](https://github.com/dellius-alexander/CRUDRepository/actions/workflows/deploy.yml/badge.svg)](https://github.com/dellius-alexander/CRUDRepository/actions/workflows/deploy.yml)\n\n---\n\n# CRUD Repository\n\n---\n## Description\n\nThe CRUDRepository is a Python project designed to provide a\ngeneric implementation of Create, Read, Update, and Delete (CRUD)\noperations for various databases. It uses the Repository design pattern\nto abstract the data access layer, allowing for easy switching between\ndifferent databases using the Factory pattern in which each database\nobject implements a Singleton object.\n\nThe project includes classes for handling different types of databases\nsuch as PostgreSQL, MySQL, and MariaDB. Each of these classes implements\na common Interface, ensuring a consistent method of interaction\nregardless of the underlying database.\n\nThe CRUDRepository also includes a Repository class that provides generic\nCRUD operations. This class can be used as a base for creating more specific\nrepositories, like the test Repository UserRepository included in the project, which is\ndesigned to manage User instances.\n\nThe project uses SQLAlchemy for ORM, providing a high-level, Pythonic\ninterface for database operations. It also includes a DatabaseFactory for\ncreating instances of the appropriate database class based on provided\nconfiguration. The DatabaseFactory implements the Singleton design pattern, \nensuring that only one instance of each database type is created.\n\nIn summary, CRUDRepository is a flexible and extensible\nfoundation for Python applications that require database interactions,\nabstracting the complexities of direct database access and providing a\nclear and simple interface for performing CRUD operations.\n\n## Class Diagram\n\n```mermaid\nclassDiagram\n    namespace Models {\n        class Base {\n        }\n      class User {\n          +id: int\n          +username: str\n          +password: str\n      }\n    }\n    namespace Databases {\n        class IDatabase {\n            \u003c\u003c interface \u003e\u003e\n          +connect(): Connection\n          +get_session(): scoped_session\n        }\n        class PostgreSQLDatabase {\n            +session: scoped_session\n            #engine: Engine\n            +connect(): Connection\n            +get_session(): scoped_session\n        }\n        class MySQLDatabase {\n            +session: scoped_session\n            #engine: Engine\n            +connect(): Connection\n            +get_session(): scoped_session\n        }\n        class MariaDBDatabase {\n            +session: scoped_session\n            #engine: Engine\n            +connect(): Connection\n            +get_session(): scoped_session\n        }\n        class DatabaseFactory {\n            _instances: Dict$\n            +create(config: dict) : IDatabase$\n        }\n    }\n\n    namespace Repositories {\n        class IRepository ~Base as T~ {\n            \u003c\u003c interface \u003e\u003e\n          +create(entity: T) : T\n          +read(id) : T\n          +update(entity: T): T\n          +delete(entity: T): None\n      }\n        class Repository {\n          #database: IDatabase\n          #model: T\n          +create(entity: T) : T\n          +read(id) : T\n          +update(entity: T): T\n          +delete(entity: T): None\n      }\n        class UserRepository {\n            +__init__(database: IDatabase)\n        }\n    }\n\n\n\n    IDatabase \u003c|-- PostgreSQLDatabase: Implements\n    IDatabase \u003c|-- MySQLDatabase: Implements\n    IDatabase \u003c|-- MariaDBDatabase: Implements\n\n\n    IRepository ~Base as T~ \u003c|-- Repository : Implements\n    Repository \u003c|-- UserRepository: Implements\n    PostgreSQLDatabase \"1\" -- \"1\" Repository: Uses\n    MySQLDatabase \"1\" -- \"1\" Repository: Uses\n    MariaDBDatabase \"1\" -- \"1\" Repository: Uses\n    UserRepository \"1\" -- \"1\" User: Manages\n    Base \u003c|-- User: Implements\n    DatabaseFactory --\u003e PostgreSQLDatabase: \u003c\u003c create \u003e\u003e\n    DatabaseFactory --\u003e MySQLDatabase: \u003c\u003c create \u003e\u003e\n    DatabaseFactory --\u003e MariaDBDatabase: \u003c\u003c create \u003e\u003e\n```\n\n### In this diagram (Class Diagram):\n\n* `Base` is a base class for all models, and `User` is a specific model that extends `Base`.\n* `IDatabase` is an abstract base class that defines the interface for a database. `PostgreSQLDatabase`, `MySQLDatabase`, and `MariaDBDatabase` are concrete implementations of this interface.\n* `DatabaseFactory` is a factory class that creates instances of `PostgreSQLDatabase`, `MySQLDatabase`, or `MariaDBDatabase` based on the provided configuration. It ensures that only one instance of each database type is created, implementing the Singleton design pattern.\n* `IRepository ~T~` is an abstract base class that defines the interface for a repository, and `Repository ~Base~` is a generic implementation of this interface that is bound to the `Base` model class.\n* `UserRepository` is a specific repository that manages `User` instances.\n* `PostgreSQLDatabase`, `MySQLDatabase`, and `MariaDBDatabase` are used by `Repository ~Base~`, and `UserRepository` manages `User` instances.\n\n---\n\n## Sequence Diagrams\n\n---\n\n### Create Specific Database Type\n\n```mermaid\nsequenceDiagram\n    box Configuration Specific Database Type\n    actor Client\n    participant DatabaseFactory\n    participant PostgreSQLDatabase\n    participant MySQLDatabase\n    participant MariaDBDatabase\n    end\n    \n    Client-\u003e\u003eDatabaseFactory: create_database(config): IDatabase\n    alt db_name == 'postgresql'\n        DatabaseFactory--\u003e\u003ePostgreSQLDatabase: create(config): IDatabase\n        PostgreSQLDatabase--\u003e\u003eDatabaseFactory: return PostgreSQLDatabase\n    else db_name == 'mysql'\n        DatabaseFactory--\u003e\u003eMySQLDatabase: create(config): IDatabase\n        MySQLDatabase--\u003e\u003eDatabaseFactory: return MySQLDatabase\n    else db_name == 'mariadb'\n        DatabaseFactory--\u003e\u003eMariaDBDatabase: create(config): IDatabase\n        MariaDBDatabase--\u003e\u003eDatabaseFactory: return MariaDBDatabase\n    end\n    DatabaseFactory--\u003e\u003eClient: return Database\n```\n\n#### In this diagram (Sequence Diagram):\n\nThe diagram illustrates how a client can configure a database connection based on a provided database type. This process highlights the roles of various classes and their collaborative interactions. \n\n#### Classes:\n\n* **Client**: The actor initiating the database configuration process.\n* **DatabaseFactory**: A factory class responsible for creating specific database instances.\n* **PostgreSQLDatabase, MySQLDatabase, MariaDBDatabase**: Concrete database classes representing the different database types.\n* **IDatabase**: An interface defining the contract for database interactions.\n\n#### Interactions:\n\n* The `Client` sends a `create_database` request, including configuration details, to the `DatabaseFactory`.\n* The `DatabaseFactory` determines the appropriate database type (postgresql, mysql, or mariadb).\n* Based on the type, the `DatabaseFactory` creates an instance of the corresponding database class.\n* The created database object (implementing the `IDatabase` interface) is returned to the `Client`.\n\n---\n\n### Create Model Specific Repository\n\n```mermaid\nsequenceDiagram\n    box Create Model Specific Repository\n    actor Client\n    participant Repository\n    participant UserRepository\n    participant User as User Model\n    end\n    \n  Client-\u003e\u003eRepository: createUserRepository(database: IDatabase, user: User): IRepository\n  Repository-\u003e\u003eClient: return Repository(database, user) as UserRepository\n```\n\n#### In this diagram (Sequence Diagram):\n\nThis sequence diagram illustrates the process of creating a repository tailored specifically for managing `User` data. This provides organized data access for the `Client`.\n\n#### Classes:\n\n* `Client`: Initiates the repository creation process.\n* `User Repository`: A repository designed to handle all data operations related to the `User` model.\n* `Repository`: A base class offering fundamental data access functionality.\n* `User Model`: The model representing a user within the system.\n\n#### Interactions:\n\n* The `Client` sends the `createUserRepository` request to the `Repository` class, providing a database (`IDatabase`) instance and the `User` model.\n* The `Repository` constructs a repository instance, specifically configured to work with the `User` model and the supplied database.\n* The `Repository` returns the newly formed `User Repository` object back to the `Client`.\n\n---\n\n### Perform CRUD Operation on User model\n\n```mermaid\nsequenceDiagram \n    box Perform CRUD Operation\n    participant Client\n    participant UserRepository\n    participant Repository\n    participant User as User Model\n    end\n    Client-\u003e\u003eUserRepository: performOperation(operation: string, user_repo: UserRepository)\n    alt operation == 'create'\n            UserRepository-\u003e\u003eRepository: create(user: User): User\n            Repository-\u003e\u003eUser: create(user: User): User\n            User-\u003e\u003eRepository: return {status: Success/Error, object: User}\n            Repository--\u003e\u003eUserRepository: return {status: Success/Error, object: User}\n    else    operation == 'read'\n            UserRepository-\u003e\u003eRepository: read(id: int): User\n            Repository-\u003e\u003eUser: read(User, id): User\n            User--\u003e\u003eRepository: return User / None\n            Repository--\u003e\u003eUserRepository: return User / None\n    else    operation == 'update'\n            UserRepository-\u003e\u003eRepository: update(user: User): User\n            Repository-\u003e\u003eUser: update(user: User): User\n            User-\u003e\u003eRepository: return {status: Success/Error, object: User}\n            Repository--\u003e\u003eUserRepository: return {status: Success/Error, object: User}\n    else    operation == 'delete'\n            UserRepository-\u003e\u003eRepository: delete(user: User): Success/Error\n            Repository-\u003e\u003eUser: delete(user: User): Success/Error\n            User-\u003e\u003eRepository: return Success/Error\n            Repository--\u003e\u003eUserRepository: return Success/Error\n    end\n    UserRepository--\u003e\u003eClient: return {status: Success/Error, object: User}\n```\n\n### In this diagram (Sequence Diagram):\n\nThis diagram depicts how a client performs CRUD (Create, Read, Update, Delete) operations on the User model through the `UserRepository`.\n\n* `Client`: Triggers CRUD operations by calling performOperation on the UserRepository.\n* `UserRepository`: Delegates the operation to the underlying Repository, providing context (User model information).\n* `Repository`:  Interacts directly with the IDatabase instance to execute the database operations.\n* `User Model`: Represents the abstraction for database interaction.\n\n#### Interactions:\n\n* The `Client` calls performOperation on the `UserRepository`, specifying the desired operation type (create, read, update, or delete) .\n* The `UserRepository` delegates the execution to the `Repository` instance.\n* The `Repository` interacts with the underlying `Database` implementation to perform the specified database operation.\n* The success or failure result, along with any data, is returned back through the `Repository` and `UserRepository` layers to the `Client`.\n\n#### Key Points:\n\n* `Abstraction`: Interfaces like IDatabase promote flexibility, allowing the system to swap database implementations easily.\n\n* `Separation of Concerns`:  The diagrams demonstrate how responsibilities are divided: \n  * The client manages user interaction.\n  * Factories handle object creation.\n  * Repositories encapsulate data access logic.\n  * Database classes focus on database-specific interactions.\n\n---\n\n### Full Sequence Diagram for Database Configuration and CRUD Operations\n\n\n```mermaid\nsequenceDiagram\n  box Full Sequence Diagram for Database Configuration and CRUD Operations\n  actor Client\n  participant DatabaseFactory\n  participant PostgreSQLDatabase\n  participant MySQLDatabase\n  participant MariaDBDatabase\n  participant UserRepository\n  participant Repository \n  participant User as User Model\n  end\n  \n  note over Client, MariaDBDatabase: Configuration specifies database type\n  note over UserRepository, User: **CRUD Operations**\n\n  Client-\u003e\u003eDatabaseFactory: create_database(config): IDatabase\n  alt db_name == 'postgresql'\n    DatabaseFactory-\u003e\u003ePostgreSQLDatabase: create(config): IDatabase\n    PostgreSQLDatabase-\u003e\u003eDatabaseFactory: return PostgreSQLDatabase\n  else db_name == 'mysql'\n    DatabaseFactory-\u003e\u003eMySQLDatabase: create(config): IDatabase\n    MySQLDatabase-\u003e\u003eDatabaseFactory: return MySQLDatabase\n  else db_name == 'mariadb'\n    DatabaseFactory-\u003e\u003eMariaDBDatabase: create(config): IDatabase\n    MariaDBDatabase-\u003e\u003eDatabaseFactory: return MariaDBDatabase\n  end\n  DatabaseFactory-\u003e\u003eClient: return database \n\n  Client-\u003e\u003eRepository: createUserRepository(database, user): IRepository\n  Repository-\u003e\u003eClient: return Repository(database, user) as UserRepository\n\n  Client-\u003e\u003eUserRepository: performOperation(operation: string)\n  alt operation == 'create'\n    UserRepository-\u003e\u003eRepository: create(user)\n    Repository-\u003e\u003eUser: create(user) \n    User-\u003e\u003eRepository: return {status: Success/Error, object: User}\n    Repository-\u003e\u003eUserRepository: return {status: Success/Error, object: User}\n  else operation == 'read'\n    UserRepository-\u003e\u003eRepository: read(id)\n    Repository-\u003e\u003eUser: read(id)\n    User-\u003e\u003eRepository: return User / None\n    Repository-\u003e\u003eUserRepository: return User / None\n  else operation == 'update'\n    UserRepository-\u003e\u003eRepository: update(user)\n    Repository-\u003e\u003eUser: update(user)\n    User-\u003e\u003eRepository: return {status: Success/Error, object: User}\n    Repository-\u003e\u003eUserRepository: return {status: Success/Error, object: User}\n  else operation == 'delete'\n    UserRepository-\u003e\u003eRepository: delete(user)\n    Repository-\u003e\u003eUser: delete(user)\n    User-\u003e\u003eRepository: return Success/Error\n    Repository-\u003e\u003eUserRepository: return Success/Error\n  end\n  UserRepository-\u003e\u003eClient: return {status: Success/Error, object: User/None}\n```\n\n---\n\n## Installation\n    \n```bash\npip install crud-repository\n```\n\n## Code Example Usage\n\n```python\n#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\nfrom crud_repository.db.factory import DatabaseFactory\nfrom typing import Optional\nfrom sqlalchemy import Column, Sequence, Integer, String\nfrom sqlalchemy.orm import Mapped\nfrom crud_repository.model.base import Base\nfrom db.idatabase import IDatabase\nfrom crud_repository.repo.repository import Repository\n\n\n# ---------------------------------------------------------\n# Create a User model\n# ---------------------------------------------------------\nclass User(Base):\n    __tablename__ = \"user\"\n\n    id: Mapped[int] = Column(\n        Integer,\n        Sequence(\"user_id_seq\"),\n        primary_key=True,\n        autoincrement=True,\n        nullable=False,\n        unique=True,\n        index=True,\n    )\n    username: Mapped[str] = Column(String(128), nullable=False)\n    password: Mapped[Optional[str]] = Column(String(128), nullable=True)\n\n    def to_dict(self) -\u003e dict:\n        return {\"id\": self.id, \"username\": self.username, \"password\": self.password}\n\n    def as_dict(self) -\u003e dict:  # renamed from __dict__ to as_dict\n        return self.to_dict()\n\n    def __repr__(self) -\u003e str:\n        return (\n            f\"User(id={self.id!r}, name={self.username!r}, fullname={self.password!r})\"\n        )\n\n\n# ---------------------------------------------------------\n# Create a new user\n# ---------------------------------------------------------\nif __name__ == '__main__':\n    # Create a new database instance\n    db_config = {\n        'type': 'postgresql',\n        'db_name': 'volunteer',\n        'user': \"postgres\",\n        'password': \"adminpassword\",\n        'host': \"127.0.0.1\",\n        'port': \"5432\"\n    }\n    # Create a new database instance\n    db = DatabaseFactory.create(db_config)\n\n    # Create a User Repository instance with the \n    # database instance and the User model\n    user_repo = Repository(db, User)\n\n    # Create a new user\n    user = User(username='Candy', password='password')\n\n    # Add the user to the database\n    user_repo.create(user)\n```\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdellius-alexander%2Fcrudrepository","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdellius-alexander%2Fcrudrepository","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdellius-alexander%2Fcrudrepository/lists"}