{"id":13468439,"url":"https://github.com/dgilland/sqlservice","last_synced_at":"2025-04-05T20:04:36.312Z","repository":{"id":57470636,"uuid":"59388509","full_name":"dgilland/sqlservice","owner":"dgilland","description":"The missing SQLAlchemy ORM interface.","archived":false,"fork":false,"pushed_at":"2024-01-27T02:35:38.000Z","size":647,"stargazers_count":176,"open_issues_count":3,"forks_count":8,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-03-29T19:05:19.435Z","etag":null,"topics":["database","orm","python","python3","sql","sqlalchemy"],"latest_commit_sha":null,"homepage":"https://sqlservice.readthedocs.io","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/dgilland.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.rst","contributing":"CONTRIBUTING.rst","funding":null,"license":"LICENSE.rst","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.rst","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-05-22T00:56:21.000Z","updated_at":"2025-01-30T10:48:29.000Z","dependencies_parsed_at":"2024-06-19T00:07:18.325Z","dependency_job_id":"eb6e6b74-9bd0-46b0-bbca-59670840dbd4","html_url":"https://github.com/dgilland/sqlservice","commit_stats":{"total_commits":290,"total_committers":4,"mean_commits":72.5,"dds":0.03448275862068961,"last_synced_commit":"0be2bb62b2655916f5958e7eccaed63e83f1fe7b"},"previous_names":[],"tags_count":52,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgilland%2Fsqlservice","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgilland%2Fsqlservice/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgilland%2Fsqlservice/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgilland%2Fsqlservice/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dgilland","download_url":"https://codeload.github.com/dgilland/sqlservice/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247393566,"owners_count":20931812,"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":["database","orm","python","python3","sql","sqlalchemy"],"created_at":"2024-07-31T15:01:10.766Z","updated_at":"2025-04-05T20:04:36.289Z","avatar_url":"https://github.com/dgilland.png","language":"Python","readme":"sqlservice\n**********\n\n|version| |build| |coveralls| |license|\n\n\nThe missing SQLAlchemy ORM interface.\n\n\nLinks\n=====\n\n- Project: https://github.com/dgilland/sqlservice\n- Documentation: http://sqlservice.readthedocs.io\n- PyPI: https://pypi.python.org/pypi/sqlservice/\n- Github Actions: https://github.com/dgilland/sqlservice/actions\n\n\nIntroduction\n============\n\nSo what exactly is ``sqlservice`` and what does \"the missing SQLAlchemy ORM interface\" even mean? SQLAlchemy is a fantastic library and features a superb ORM layer. However, one thing SQLAlchemy lacks is a unified interface for easily interacting with your database through your ORM models. This is where ``sqlservice`` comes in. It's interface layer on top of SQLAlchemy's session manager and ORM layer that provides a single point to manage your database connection/session, create/reflect/drop your database objects, and easily persist/destroy model objects.\n\nFeatures\n--------\n\nThis library is meant to enhance your usage of SQLAlchemy. SQLAlchemy is great and this library tries to build upon that by providing useful abstractions on top of it.\n\n- Sync and asyncio database clients to manage ORM sessions with enhanced session classes.\n- Base class for a declarative ORM Model that makes updating model columns and relationships easier and converting to a dictionary a breeze.\n- Decorator-based event register for SQLAlchemy ORM events that can be used at the model class level. No need to register the event handler outside of the class definition.\n- And more!\n\n\nRequirements\n------------\n\n- Python \u003e= 3.7\n- `SQLAlchemy \u003chttp://www.sqlalchemy.org/\u003e`_ \u003e= 2.0\n\n\nQuickstart\n==========\n\nFirst, install using pip:\n\n\n::\n\n    pip install sqlservice\n\n\nThen, define some ORM models:\n\n.. code-block:: python\n\n    import re\n    import typing as t\n\n    from sqlalchemy import ForeignKey, orm, types\n    from sqlalchemy.orm import Mapped, mapped_column\n\n    from sqlservice import declarative_base, event\n\n\n    Model = declarative_base()\n\n    class User(Model):\n        __tablename__ = \"user\"\n\n        id: Mapped[int] = mapped_column(types.Integer(), primary_key=True)\n        name: Mapped[t.Optional[str]] = mapped_column(types.String(100))\n        email: Mapped[t.Optional[str]] = mapped_column(types.String(100))\n        phone: Mapped[t.Optional[str]] = mapped_column(types.String(10))\n\n        roles: Mapped[t.List[\"UserRole\"]] = orm.relationshipship(\"UserRole\")\n\n        @event.on_set(\"phone\", retval=True)\n        def on_set_phone(self, value):\n            # Strip non-numeric characters from phone number.\n            return re.sub(\"[^0-9]\", \"\", value)\n\n\n    class UserRole(Model):\n        __tablename__ = \"user_role\"\n\n        id: Mapped[int] = mapped_column(types.Integer(), primary_key=True)\n        user_id: Mapped[int] = mapped_column(types.Integer(), ForeignKey(\"user.id\"), nullable=False)\n        role: Mapped[str] = mapped_column(types.String(25), nullable=False)\n\n\nNext, configure the database client:\n\n.. code-block:: python\n\n    from sqlservice import AsyncDatabase, Database\n\n    db = Database(\n        \"sqlite:///db.sql\",\n        model_class=Model,\n        isolation_level=\"SERIALIZABLE\",\n        echo=True,\n        echo_pool=False,\n        pool_size=5,\n        pool_timeout=30,\n        pool_recycle=3600,\n        max_overflow=10,\n        autoflush=True,\n    )\n\n    # Same options as above are supported but will default to compatibility with SQLAlchemy asyncio mode.\n    async_db = AsyncDatabase(\"sqlite:///db.sql\", model_class=Model)\n\n\nPrepare the database by creating all tables:\n\n.. code-block:: python\n\n    db.create_all()\n    await async_db.create_all()\n\n\nFinally (whew!), start interacting with the database.\n\nInsert a new record in the database:\n\n.. code-block:: python\n\n    user = User(name='Jenny', email=jenny@example.com, phone='555-867-5309')\n    with db.begin() as session:\n        session.save(user)\n\n    async with db.begin() as session:\n        await session.save(user)\n\n\nFetch records:\n\n.. code-block:: python\n\n    session = db.session()\n    assert user is session.get(User, user.id)\n    assert user is session.first(User.select())\n    assert user is session.all(User.select().where(User.id == user.id)[0]\n\n\nSerialize to a ``dict``:\n\n.. code-block:: python\n\n    assert user.to_dict() == {\n        \"id\": 1,\n        \"name\": \"Jenny\",\n        \"email\": \"jenny@example.com\",\n        \"phone\": \"5558675309\"\n    }\n\n    assert dict(user) == user.to_dict()\n\n\nUpdate the record and save:\n\n.. code-block:: python\n\n    user.phone = '222-867-5309'\n    with db.begin() as session:\n        session.save(user)\n\n    async with async_db.begin() as session:\n        await session.save(user)\n\n\nUpsert on primary key automatically:\n\n.. code-block:: python\n\n    other_user = User(id=1, name=\"Jenny\", email=\"jenny123@example.com\", phone=\"5558675309\")\n    with db.begin() as session:\n        session.save(other_user)\n    assert user is other_user\n\nFor more details, please see the full documentation at http://sqlservice.readthedocs.io.\n\n\n\n.. |version| image:: http://img.shields.io/pypi/v/sqlservice.svg?style=flat-square\n    :target: https://pypi.python.org/pypi/sqlservice/\n\n.. |build| image:: https://img.shields.io/github/actions/workflow/status/dgilland/sqlservice/main.yml?branch=master\u0026style=flat-square\n    :target: https://github.com/dgilland/sqlservice/actions\n\n.. |coveralls| image:: http://img.shields.io/coveralls/dgilland/sqlservice/master.svg?style=flat-square\n    :target: https://coveralls.io/r/dgilland/sqlservice\n\n.. |license| image:: http://img.shields.io/pypi/l/sqlservice.svg?style=flat-square\n    :target: https://pypi.python.org/pypi/sqlservice/\n","funding_links":[],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdgilland%2Fsqlservice","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdgilland%2Fsqlservice","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdgilland%2Fsqlservice/lists"}