tortoise-plus


Nametortoise-plus JSON
Version 0.2.0 PyPI version JSON
download
home_pageNone
Summaryadd sqlcipher support
upload_time2025-07-12 04:54:04
maintainerNone
docs_urlNone
authortianqing
requires_python>=3.9
licenseApache-2.0
keywords sql mysql postgres psql sqlite aiosqlite asyncpg relational database rdbms orm object mapper async asyncio aio psycopg
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ============
Tortoise ORM
============

.. image:: https://img.shields.io/pypi/v/tortoise-plus.svg?style=flat
   :target: https://pypi.python.org/pypi/tortoise-plus
.. image:: https://pepy.tech/badge/tortoise-plus/month
   :target: https://pepy.tech/project/tortoise-plus
.. image:: https://github.com/tortoise/tortoise-plus/workflows/gh-pages/badge.svg
   :target: https://github.com/tortoise/tortoise-plus/actions?query=workflow:gh-pages
.. image:: https://github.com/tortoise/tortoise-plus/actions/workflows/ci.yml/badge.svg?branch=develop
   :target: https://github.com/tortoise/tortoise-plus/actions?query=workflow:ci
.. image:: https://coveralls.io/repos/github/tortoise/tortoise-plus/badge.svg
   :target: https://coveralls.io/github/tortoise/tortoise-plus
.. image:: https://app.codacy.com/project/badge/Grade/844030d0cb8240d6af92c71bfac764ff
   :target: https://www.codacy.com/gh/tortoise/tortoise-plus/dashboard?utm_source=github.com&utm_medium=referral&utm_content=tortoise/tortoise-plus&utm_campaign=Badge_Grade

Introduction
============

Tortoise ORM is an easy-to-use ``asyncio`` ORM *(Object Relational Mapper)* inspired by Django.

You can find the docs at `Documentation <https://tortoise.github.io>`_

.. note::
   Tortoise ORM is a young project and breaking changes are to be expected.
   We keep a `Changelog <https://tortoise.github.io/CHANGELOG.html>`_ and it will have possible breakage clearly documented.

Tortoise ORM supports CPython 3.9 and later for SQLite, MySQL, PostgreSQL, Microsoft SQL Server, and Oracle.

Why was Tortoise ORM built?
---------------------------

Tortoise ORM was built to provide a lightweight, async-native Object-Relational Mapper for Python with a familiar Django-like API.

Tortoise ORM performs well when compared to other Python ORMs. In `our benchmarks <https://github.com/tortoise/orm-benchmarks>`_, where we measure different read and write operations (rows/sec, more is better), it's trading places with Pony ORM:

.. image:: https://raw.githubusercontent.com/tortoise/tortoise-plus/develop/docs/ORM_Perf.png
    :target: https://github.com/tortoise/orm-benchmarks

How is an ORM useful?
---------------------

An Object-Relational Mapper (ORM) abstracts database interactions, allowing developers to work with databases using high-level, object-oriented code instead of raw SQL.

* Reduces boilerplate SQL, allowing faster development with cleaner, more readable code.
* Helps prevent SQL injection by using parameterized queries.
* Centralized schema and relationship definitions make code easier to manage and modify.
* Handles schema changes through version-controlled migrations.

Getting Started
===============

Installation
------------

The following table shows the available installation options for different databases (note that there are multiple options of clients for some databases):

.. list-table:: Available Installation Options
   :header-rows: 1
   :widths: 30 70

   * - Database
     - Installation Command
   * - SQLite
     - ``pip install tortoise-plus``
   * - PostgreSQL (psycopg)
     - ``pip install tortoise-plus[psycopg]``
   * - PostgreSQL (asyncpg)
     - ``pip install tortoise-plus[asyncpg]``
   * - MySQL (aiomysql)
     - ``pip install tortoise-plus[aiomysql]``
   * - MySQL (asyncmy)
     - ``pip install tortoise-plus[asyncmy]``
   * - MS SQL
     - ``pip install tortoise-plus[asyncodbc]``
   * - Oracle
     - ``pip install tortoise-plus[asyncodbc]``


Quick Tutorial
--------------

Define the models by inheriting from ``tortoise.models.Model``.


.. code-block:: python3

    from tortoise.models import Model
    from tortoise import fields

    class Tournament(Model):
        id = fields.IntField(primary_key=True)
        name = fields.CharField(max_length=20)


    class Event(Model):
        id = fields.BigIntField(primary_key=True)
        name = fields.TextField()
        tournament = fields.ForeignKeyField('models.Tournament', related_name='events', on_delete=fields.OnDelete.CASCADE)
        participants = fields.ManyToManyField('models.Team', related_name='events', through='event_team', on_delete=fields.OnDelete.SET_NULL)


    class Team(Model):
        id = fields.UUIDField(primary_key=True)
        name = fields.CharField(max_length=20, unique=True)


After defining the models, Tortoise ORM needs to be initialized to establish the relationships between models and connect to the database.
The code below creates a connection to a SQLite DB database with the ``aiosqlite`` client. ``generate_schema`` sets up schema on an empty database.
``generate_schema`` is for development purposes only, check out ``aerich`` or other migration tools for production use.

.. code-block:: python3

    from tortoise import Tortoise, run_async

    async def init():
        # Here we connect to a SQLite DB file.
        # also specify the app name of "models"
        # which contain models from "app.models"
        await Tortoise.init(
            db_url='sqlite://db.sqlite3',
            modules={'models': ['app.models']}
        )
        # Generate the schema
        await Tortoise.generate_schemas()

    run_async(main())

``run_async`` is a helper function to run simple Tortoise scripts. Check out `Documentation <https://tortoise.github.io>`_ for FastAPI, Sanic and other integrations.

With the Tortoise initialized, the models are available for use:

.. code-block:: python3

    async def main():
        await Tortoise.init(
            db_url='sqlite://db.sqlite3',
            modules={'models': ['app.models']}
        )
        await Tortoise.generate_schemas()

        # Creating an instance with .save()
        tournament = Tournament(name='New Tournament')
        await tournament.save()

        # Or with .create()
        await Event.create(name='Without participants', tournament=tournament)
        event = await Event.create(name='Test', tournament=tournament)
        participants = []
        for i in range(2):
            team = await Team.create(name='Team {}'.format(i + 1))
            participants.append(team)

        # Many to Many Relationship management is quite straightforward
        # (there are .remove(...) and .clear() too)
        await event.participants.add(*participants)

        # Iterate over related entities with the async context manager
        async for team in event.participants:
            print(team.name)

        # The related entities are cached and can be iterated in the synchronous way afterwards
        for team in event.participants:
            pass

        # Use prefetch_related to fetch related objects
        selected_events = await Event.filter(
            participants=participants[0].id
        ).prefetch_related('participants', 'tournament')
        for event in selected_events:
            print(event.tournament.name)
            print([t.name for t in event.participants])

        # Prefetch multiple levels of related entities
        await Team.all().prefetch_related('events__tournament')

        # Filter and order by related models too
        await Tournament.filter(
            events__name__in=['Test', 'Prod']
        ).order_by('-events__participants__name').distinct()

    run_async(main())


Learn more at the `documentation site <https://tortoise.github.io>`_


Migration
=========

Tortoise ORM uses `Aerich <https://github.com/tortoise/aerich>`_ as its database migration tool, see more detail at its `docs <https://github.com/tortoise/aerich>`_.

Contributing
============

Please have a look at the `Contribution Guide <docs/CONTRIBUTING.rst>`_.

ThanksTo
========

Powerful Python IDE `Pycharm <https://www.jetbrains.com/pycharm/>`_
from `Jetbrains <https://jb.gg/OpenSourceSupport>`_.

.. image:: https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg
    :target: https://jb.gg/OpenSourceSupport

License
=======

This project is licensed under the Apache License - see the `LICENSE.txt <LICENSE.txt>`_ file for details.


            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "tortoise-plus",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "sql, mysql, postgres, psql, sqlite, aiosqlite, asyncpg, relational, database, rdbms, orm, object mapper, async, asyncio, aio, psycopg",
    "author": "tianqing",
    "author_email": "tianqing108@126.com",
    "download_url": "https://files.pythonhosted.org/packages/56/29/8e8151b9b257ef47d75fbc047a9496a05dffab2196b49893e135aff2f5e7/tortoise_plus-0.2.0.tar.gz",
    "platform": null,
    "description": "============\nTortoise ORM\n============\n\n.. image:: https://img.shields.io/pypi/v/tortoise-plus.svg?style=flat\n   :target: https://pypi.python.org/pypi/tortoise-plus\n.. image:: https://pepy.tech/badge/tortoise-plus/month\n   :target: https://pepy.tech/project/tortoise-plus\n.. image:: https://github.com/tortoise/tortoise-plus/workflows/gh-pages/badge.svg\n   :target: https://github.com/tortoise/tortoise-plus/actions?query=workflow:gh-pages\n.. image:: https://github.com/tortoise/tortoise-plus/actions/workflows/ci.yml/badge.svg?branch=develop\n   :target: https://github.com/tortoise/tortoise-plus/actions?query=workflow:ci\n.. image:: https://coveralls.io/repos/github/tortoise/tortoise-plus/badge.svg\n   :target: https://coveralls.io/github/tortoise/tortoise-plus\n.. image:: https://app.codacy.com/project/badge/Grade/844030d0cb8240d6af92c71bfac764ff\n   :target: https://www.codacy.com/gh/tortoise/tortoise-plus/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=tortoise/tortoise-plus&amp;utm_campaign=Badge_Grade\n\nIntroduction\n============\n\nTortoise ORM is an easy-to-use ``asyncio`` ORM *(Object Relational Mapper)* inspired by Django.\n\nYou can find the docs at `Documentation <https://tortoise.github.io>`_\n\n.. note::\n   Tortoise ORM is a young project and breaking changes are to be expected.\n   We keep a `Changelog <https://tortoise.github.io/CHANGELOG.html>`_ and it will have possible breakage clearly documented.\n\nTortoise ORM supports CPython 3.9 and later for SQLite, MySQL, PostgreSQL, Microsoft SQL Server, and Oracle.\n\nWhy was Tortoise ORM built?\n---------------------------\n\nTortoise ORM was built to provide a lightweight, async-native Object-Relational Mapper for Python with a familiar Django-like API.\n\nTortoise ORM performs well when compared to other Python ORMs. In `our benchmarks <https://github.com/tortoise/orm-benchmarks>`_, where we measure different read and write operations (rows/sec, more is better), it's trading places with Pony ORM:\n\n.. image:: https://raw.githubusercontent.com/tortoise/tortoise-plus/develop/docs/ORM_Perf.png\n    :target: https://github.com/tortoise/orm-benchmarks\n\nHow is an ORM useful?\n---------------------\n\nAn Object-Relational Mapper (ORM) abstracts database interactions, allowing developers to work with databases using high-level, object-oriented code instead of raw SQL.\n\n* Reduces boilerplate SQL, allowing faster development with cleaner, more readable code.\n* Helps prevent SQL injection by using parameterized queries.\n* Centralized schema and relationship definitions make code easier to manage and modify.\n* Handles schema changes through version-controlled migrations.\n\nGetting Started\n===============\n\nInstallation\n------------\n\nThe following table shows the available installation options for different databases (note that there are multiple options of clients for some databases):\n\n.. list-table:: Available Installation Options\n   :header-rows: 1\n   :widths: 30 70\n\n   * - Database\n     - Installation Command\n   * - SQLite\n     - ``pip install tortoise-plus``\n   * - PostgreSQL (psycopg)\n     - ``pip install tortoise-plus[psycopg]``\n   * - PostgreSQL (asyncpg)\n     - ``pip install tortoise-plus[asyncpg]``\n   * - MySQL (aiomysql)\n     - ``pip install tortoise-plus[aiomysql]``\n   * - MySQL (asyncmy)\n     - ``pip install tortoise-plus[asyncmy]``\n   * - MS SQL\n     - ``pip install tortoise-plus[asyncodbc]``\n   * - Oracle\n     - ``pip install tortoise-plus[asyncodbc]``\n\n\nQuick Tutorial\n--------------\n\nDefine the models by inheriting from ``tortoise.models.Model``.\n\n\n.. code-block:: python3\n\n    from tortoise.models import Model\n    from tortoise import fields\n\n    class Tournament(Model):\n        id = fields.IntField(primary_key=True)\n        name = fields.CharField(max_length=20)\n\n\n    class Event(Model):\n        id = fields.BigIntField(primary_key=True)\n        name = fields.TextField()\n        tournament = fields.ForeignKeyField('models.Tournament', related_name='events', on_delete=fields.OnDelete.CASCADE)\n        participants = fields.ManyToManyField('models.Team', related_name='events', through='event_team', on_delete=fields.OnDelete.SET_NULL)\n\n\n    class Team(Model):\n        id = fields.UUIDField(primary_key=True)\n        name = fields.CharField(max_length=20, unique=True)\n\n\nAfter defining the models, Tortoise ORM needs to be initialized to establish the relationships between models and connect to the database.\nThe code below creates a connection to a SQLite DB database with the ``aiosqlite`` client. ``generate_schema`` sets up schema on an empty database.\n``generate_schema`` is for development purposes only, check out ``aerich`` or other migration tools for production use.\n\n.. code-block:: python3\n\n    from tortoise import Tortoise, run_async\n\n    async def init():\n        # Here we connect to a SQLite DB file.\n        # also specify the app name of \"models\"\n        # which contain models from \"app.models\"\n        await Tortoise.init(\n            db_url='sqlite://db.sqlite3',\n            modules={'models': ['app.models']}\n        )\n        # Generate the schema\n        await Tortoise.generate_schemas()\n\n    run_async(main())\n\n``run_async`` is a helper function to run simple Tortoise scripts. Check out `Documentation <https://tortoise.github.io>`_ for FastAPI, Sanic and other integrations.\n\nWith the Tortoise initialized, the models are available for use:\n\n.. code-block:: python3\n\n    async def main():\n        await Tortoise.init(\n            db_url='sqlite://db.sqlite3',\n            modules={'models': ['app.models']}\n        )\n        await Tortoise.generate_schemas()\n\n        # Creating an instance with .save()\n        tournament = Tournament(name='New Tournament')\n        await tournament.save()\n\n        # Or with .create()\n        await Event.create(name='Without participants', tournament=tournament)\n        event = await Event.create(name='Test', tournament=tournament)\n        participants = []\n        for i in range(2):\n            team = await Team.create(name='Team {}'.format(i + 1))\n            participants.append(team)\n\n        # Many to Many Relationship management is quite straightforward\n        # (there are .remove(...) and .clear() too)\n        await event.participants.add(*participants)\n\n        # Iterate over related entities with the async context manager\n        async for team in event.participants:\n            print(team.name)\n\n        # The related entities are cached and can be iterated in the synchronous way afterwards\n        for team in event.participants:\n            pass\n\n        # Use prefetch_related to fetch related objects\n        selected_events = await Event.filter(\n            participants=participants[0].id\n        ).prefetch_related('participants', 'tournament')\n        for event in selected_events:\n            print(event.tournament.name)\n            print([t.name for t in event.participants])\n\n        # Prefetch multiple levels of related entities\n        await Team.all().prefetch_related('events__tournament')\n\n        # Filter and order by related models too\n        await Tournament.filter(\n            events__name__in=['Test', 'Prod']\n        ).order_by('-events__participants__name').distinct()\n\n    run_async(main())\n\n\nLearn more at the `documentation site <https://tortoise.github.io>`_\n\n\nMigration\n=========\n\nTortoise ORM uses `Aerich <https://github.com/tortoise/aerich>`_ as its database migration tool, see more detail at its `docs <https://github.com/tortoise/aerich>`_.\n\nContributing\n============\n\nPlease have a look at the `Contribution Guide <docs/CONTRIBUTING.rst>`_.\n\nThanksTo\n========\n\nPowerful Python IDE `Pycharm <https://www.jetbrains.com/pycharm/>`_\nfrom `Jetbrains <https://jb.gg/OpenSourceSupport>`_.\n\n.. image:: https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg\n    :target: https://jb.gg/OpenSourceSupport\n\nLicense\n=======\n\nThis project is licensed under the Apache License - see the `LICENSE.txt <LICENSE.txt>`_ file for details.\n\n",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "add sqlcipher support",
    "version": "0.2.0",
    "project_urls": {
        "Documentation": "https://tortoise-plus.readthedocs.io",
        "Homepage": "https://github.com/tortoise/tortoise-plus",
        "Repository": "https://github.com/tortoise/tortoise-plus.git"
    },
    "split_keywords": [
        "sql",
        " mysql",
        " postgres",
        " psql",
        " sqlite",
        " aiosqlite",
        " asyncpg",
        " relational",
        " database",
        " rdbms",
        " orm",
        " object mapper",
        " async",
        " asyncio",
        " aio",
        " psycopg"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b0d5b5946cae21b1515955b0b62c16bc4b7104f9059e9b3dbbb141356faca4e3",
                "md5": "c15ab12cc38014f2d9e20a7187517fb6",
                "sha256": "11460ae313f627b8858c003a485131863ba63fdc06cf281af5a3a86f23321cff"
            },
            "downloads": -1,
            "filename": "tortoise_plus-0.2.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "c15ab12cc38014f2d9e20a7187517fb6",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 174555,
            "upload_time": "2025-07-12T04:54:02",
            "upload_time_iso_8601": "2025-07-12T04:54:02.502263Z",
            "url": "https://files.pythonhosted.org/packages/b0/d5/b5946cae21b1515955b0b62c16bc4b7104f9059e9b3dbbb141356faca4e3/tortoise_plus-0.2.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "56298e8151b9b257ef47d75fbc047a9496a05dffab2196b49893e135aff2f5e7",
                "md5": "314880436bfa47b1ccc484e704213c1c",
                "sha256": "2aae09e10960de2e88ac9bf47e99ed2ee84ef39394025be0d1f75fc22ed6a718"
            },
            "downloads": -1,
            "filename": "tortoise_plus-0.2.0.tar.gz",
            "has_sig": false,
            "md5_digest": "314880436bfa47b1ccc484e704213c1c",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 129789,
            "upload_time": "2025-07-12T04:54:04",
            "upload_time_iso_8601": "2025-07-12T04:54:04.478758Z",
            "url": "https://files.pythonhosted.org/packages/56/29/8e8151b9b257ef47d75fbc047a9496a05dffab2196b49893e135aff2f5e7/tortoise_plus-0.2.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-12 04:54:04",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "tortoise",
    "github_project": "tortoise-plus",
    "github_not_found": true,
    "lcname": "tortoise-plus"
}
        
Elapsed time: 0.54980s