Metadata-Version: 1.1
Name: gino
Version: 0.7.1
Summary: GINO Is Not ORM - a Python asyncio ORM on SQLAlchemy core.
Home-page: https://github.com/fantix/gino
Author: Fantix King
Author-email: fantix.king@gmail.com
License: BSD license
Description: ====
        GINO
        ====
        
        .. image:: https://img.shields.io/pypi/v/gino.svg
                :target: https://pypi.python.org/pypi/gino
        
        .. image:: https://img.shields.io/travis/fantix/gino/master.svg
                :target: https://travis-ci.org/fantix/gino
        
        .. image:: https://img.shields.io/coveralls/github/fantix/gino/master.svg
                :target: https://coveralls.io/github/fantix/gino?branch=master
        
        .. image:: https://img.shields.io/readthedocs/python-gino/stable.svg
                :target: https://python-gino.readthedocs.io/en/latest/?badge=latest
                :alt: Documentation Status
        
        .. image:: https://pyup.io/repos/github/fantix/gino/shield.svg
                :target: https://pyup.io/repos/github/fantix/gino/
                :alt: Updates
        
        .. image:: https://img.shields.io/gitter/room/python-gino/Lobby.svg
                :target: https://gitter.im/python-gino/Lobby
                :alt: Gitter chat
        
        
        GINO - GINO Is Not ORM - is a lightweight asynchronous ORM built on top of
        SQLAlchemy_ core for Python asyncio_. Now (early 2018) GINO supports only one
        dialect asyncpg_.
        
        * Free software: BSD license
        * Requires: Python 3.5
        
        
        Documentation
        -------------
        
        * English_
        * Chinese_
        
        
        Features
        --------
        
        * Robust SQLAlchemy-asyncpg bi-translator with no hard hack
        * Asynchronous SQLAlchemy-alike engine and connection
        * Asynchronous dialect API
        * Asynchronous-friendly CRUD objective models
        * Well-considered contextual connection and transaction management
        * Reusing native SQLAlchemy core to build queries with grammar sugars
        * Support Sanic_, Tornado_ and aiohttp_
        * Rich PostgreSQL JSONB support
        
        
        Showcase
        --------
        
        .. code-block:: python
        
           import asyncio
           from gino import Gino
        
           db = Gino()
        
        
           class User(db.Model):
               __tablename__ = 'users'
        
               id = db.Column(db.Integer(), primary_key=True)
               nickname = db.Column(db.Unicode(), default='noname')
        
        
           async def main():
               await db.set_bind('postgresql://localhost/gino')
        
               # Create tables
               await db.gino.create_all()
        
               # Create object, `id` is assigned by database
               u1 = await User.create(nickname='fantix')
               print(u1.id, u1.nickname)  # 1 fantix
        
               # Returns all user objects with "d" in their nicknames
               users = await User.query.where(User.nickname.contains('d')).gino.all()
               print(users)  # [<User object>, <User object>]
        
               # Find one user object, None if not found
               user = await User.query.where(User.nickname == 'daisy').gino.first()
               print(user)  # <User object> or None
        
               # Execute complex statement and return command status
               status, result = await User.update.values(
                   nickname='No.' + db.cast(User.id, db.Unicode),
               ).where(
                   User.id > 10,
               ).gino.status()
               print(status)  # UPDATE 8
        
               # Iterate over the results of a large query in a transaction as required
               async with db.transaction():
                   async for u in User.query.order_by(User.id).gino.iterate():
                       print(u.id, u.nickname)
        
        
           asyncio.get_event_loop().run_until_complete(main())
        
        
        About The Name
        --------------
        
        About the name GINO Is Not ORM - because I don't really like ORM (smile). GINO
        does perform the Object-Relational Mapping work under the
        `Data Mapper Pattern`_, but it is just not a traditional ORM. The Objects in
        GINO are completely stateless from database - they are pure plain Python
        objects in memory. Changing their attribute values does not make them "dirty" -
        or in a different way of thinking they are always "dirty". Any access to
        database must be explicitly executed. Using GINO is more like making up SQL
        clauses with Models and Objects, executing them to make changes in database, or
        loading data from database and wrapping the results with Objects again. Objects
        are just row data containers, you are still dealing with SQL which is
        represented by Models and SQLAlchemy core grammars. Besides if you don't like
        ORM at all, you can use GINO without ORM:
        
        .. code-block:: python
        
            import sqlalchemy as sa
        
            metadata = sa.MetaData()
        
            user = sa.Table(
                'users', metadata,
                sa.Column('id', sa.BigInteger(), primary_key=True),
                sa.Column('nickname', sa.Unicode()),
            )
        
        
            import gino
        
            async def main():
                e = await gino.create_engine('postgresql://localhost/gino')
                users = await e.all(sa.select([user]))
                print(users)
                # prints something like this:
                # [(1, 'fantix'), (2, 'fantix'), (3, 'fantix'), (5, 'fantix')]
        
        
            import asyncio
        
            asyncio.get_event_loop().run_until_complete(main())
        
        or a bit more GINO-ish:
        
        .. code-block:: python
        
            from gino import Gino
        
            db = Gino()
        
            user = db.Table(
                'users', db,
                db.Column('id', db.BigInteger(), primary_key=True),
                db.Column('nickname', db.Unicode()),
            )
        
            async def main():
                async with db.with_bind('postgresql://localhost/gino'):
                    users = await db.select([user]).gino.all()
                    print(users)
        
        
            import asyncio
        
            asyncio.get_event_loop().run_until_complete(main())
        
        
        Contribute
        ----------
        
        There are a few tasks in GitHub issues marked as ``help wanted``. Please feel
        free to take any of them and pull requests are greatly welcome.
        
        To run tests:
        
        .. code-block:: console
        
           $ python setup.py test
        
        
        Credits
        -------
        
        Credit goes to all contributors listed or not listed in the AUTHORS file. This
        project is inspired by asyncpgsa_, peewee-async_ and asyncorm_. asyncpg_ and
        SQLAlchemy_ as the dependencies did most of the heavy lifting. This package was
        created with Cookiecutter_ and the `audreyr/cookiecutter-pypackage`_ project
        template.
        
        Special thanks to my wife Daisy and her outsourcing company `DecentFoX Studio`_,
        for offering me the opportunity to build this project. We are open for global
        software project outsourcing on Python, iOS and Android development.
        
        .. _Cookiecutter: https://github.com/audreyr/cookiecutter
        .. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage
        .. _SQLAlchemy: https://www.sqlalchemy.org/
        .. _asyncpg: https://github.com/MagicStack/asyncpg
        .. _PostgreSQL: https://www.postgresql.org/
        .. _asyncio: https://docs.python.org/3/library/asyncio.html
        .. _Alembic: https://bitbucket.org/zzzeek/alembic
        .. _Sanic: https://github.com/channelcat/sanic
        .. _asyncpgsa: https://github.com/CanopyTax/asyncpgsa
        .. _peewee-async: https://github.com/05bit/peewee-async
        .. _asyncorm: https://github.com/monobot/asyncorm
        .. _Tornado: http://www.tornadoweb.org/
        .. _English: https://python-gino.readthedocs.io/
        .. _Chinese: https://python-gino.readthedocs.io/zh/latest/
        .. _DecentFoX Studio: https://decentfox.com/
        .. _`Data Mapper Pattern`: https://en.wikipedia.org/wiki/Data_mapper_pattern
        .. _aiohttp: https://github.com/aio-libs/aiohttp
        
        
        =======
        History
        =======
        
        GINO 0.7
        --------
        
        This is also version 1.0 beta 3.
        
        0.7.1 (2018-05-03)
        ^^^^^^^^^^^^^^^^^^
        
        * Added support for inline model constraints (Contributed by Kinware in #198)
        * Added docs and tests for using SSL (#202)
        * Added ``declared_attr`` (#204)
        * Allowed ``ModelLoader`` passively load partial model (#216)
        
        0.7.0 (2018-04-18)
        ^^^^^^^^^^^^^^^^^^
        
        * Added Python 3.5 support (#187)
        * Added support to use ``dict`` as ident for ``Model.get`` (#192)
        * Added result loader (partial relationship support) (#13)
        * Added documentation on relationship and transaction (#146)
        
        
        GINO 0.6
        --------
        
        This is also version 1.0 beta 2.
        
        Migrating to GINO 0.6
        ^^^^^^^^^^^^^^^^^^^^^
        
        1. Task Local
        """""""""""""
        
        We created a new Python package aiocontextvars_ from previous ``local.py``. If
        you made use of the task local features, you should install this package.
        
        Previous ``gino.enable_task_local()`` and ``gino.disable_task_local()`` are
        replaced by ``aiocontextvars.enable_inherit()`` and
        ``aiocontextvars.disable_inherit()``. However in GINO 0.5 they controls the
        whole task local feature switch, while aiocontextvars_ by default offers task
        local even without ``enable_inherit()``, which controls whether the local
        storage should be passed between chained tasks. When enabled, it behaves the
        same as enabled in 0.5, but you cannot completely turn off the task local
        feature while aiocontextvars_ is installed.
        
        There is no ``gino.get_local()`` and ``gino.reset_local()`` relevant in
        aiocontextvars_. The similar thing is ``aiocontextvars.ContextVar`` instance
        through its ``get()``, ``set()`` and ``delete()`` methods.
        
        Previous ``gino.is_local_root()`` is now
        ``not aiocontextvars.Context.current().inherited``.
        
        2. Engine
        """""""""
        
        GINO 0.6 hides ``asyncpg.Pool`` behind the new SQLAlchemy-alike
        ``gino.GinoEngine``. Instead of doing this in 0.5::
        
            async with db.create_pool('postgresql://...') as pool:
                # your code here
        
        You should change it to this in 0.6::
        
            async with db.with_bind('postgresql://...') as engine:
                # your code here
        
        This equals to::
        
            engine = await gino.create_engine('postgresql://...')
            db.bind = engine
            try:
                # your code here
            finally:
                db.bind = None
                await engine.close()
        
        Or::
        
            engine = await db.set_bind('postgresql://...')
            try:
                # your code here
            finally:
                await db.pop_bind().close()
        
        Or even this::
        
            db = await gino.Gino('postgresql://...')
            try:
                # your code here
            finally:
                await db.pop_bind().close()
        
        Choose whichever suits you the best.
        
        Obviously ``GinoEngine`` doesn't provide ``asyncpg.Pool`` methods directly any
        longer, but you can get the underlying ``asyncpg.Pool`` object through
        ``engine.raw_pool`` property.
        
        ``GinoPool.get_current_connection()`` is now changed to ``current_connection``
        property on ``GinoEngine`` instances to support multiple engines.
        
        ``GinoPool.execution_option`` is gone, instead ``update_execution_options()``
        on ``GinoEngine`` instance is available.
        
        ``GinoPool().metadata`` is gone, ``dialect`` is still available.
        
        ``GinoPool.release()`` is removed in ``GinoEngine`` and ``Gino``, the
        ``release()`` method on ``GinoConnection`` object should be used instead.
        
        These methods exist both in 0.5 ``GinoPool`` and 0.6 ``GinoEngine``:
        ``close()``, ``acquire()``, ``all()``, ``first()``, ``scalar()``, ``status()``.
        
        3. GinoConnection
        """""""""""""""""
        
        Similarly, ``GinoConnection`` in 0.6 is no longer a subclass of
        ``asyncpg.Connection``, instead it has a ``asyncpg.Connection`` instance,
        accessable through ``GinoConnection.raw_connection`` property.
        
        ``GinoConnection.metadata`` is deleted in 0.6, while ``dialect`` remained.
        
        ``GinoConnection.execution_options()`` is changed from a mutable dict in 0.5 to
        a method returning a copy of current connection with the new options, the same
        as SQLAlchemy behavior.
        
        ``GinoConnection.release()`` is still present, but its default behavior has
        been changed to permanently release this connection. You should add argument
        ``permanent=False`` to remain its previous behavior.
        
        And ``all()``, ``first()``, ``scalar()``, ``status()``, ``iterate()``,
        ``transaction()`` remained in 0.6.
        
        4. Query API
        """"""""""""
        
        All five query APIs ``all()``, ``first()``, ``scalar()``, ``status()``,
        ``iterate()`` now accept the same parameters as SQLAlchemy ``execute()``,
        meaning they accept raw SQL text, or multiple sets of parameters for
        "executemany". Please note, if the parameters are recognized as "executemany",
        none of the methods will return anything. Meanwhile, they no longer accept the
        parameter ``bind`` if they did. Just use the API on the ``GinoEngine`` or
        ``GinoConnection`` object instead.
        
        5. Transaction
        """"""""""""""
        
        Transaction interface is rewritten. Now in 0.6, a ``GinoTransaction`` object is
        provided consistently from all 3 methods::
        
            async with db.transaction() as tx:
                # within transaction
        
            async with engine.transaction() as tx:
                # within transaction
        
            async with engine.acquire() as conn:
                async with conn.transaction() as tx:
                    # within transaction
        
        And different usage with ``await``::
        
            tx = await db.transaction()
            try:
                # within transaction
                await tx.commit()
            except:
                await tx.rollback()
                raise
        
        The ``GinoConnection`` object is available at ``tx.connection``, while
        underlying transaction object from database driver is available at
        ``tx.transaction`` - for asyncpg it is an ``asyncpg.transaction.Transaction``
        object.
        
        0.6.5 (2018-04-18)
        ^^^^^^^^^^^^^^^^^^
        
        * Abandoned 0.6.4 and keep 0.6.x stable
        * Backported doc for transaction
        
        0.6.4 (2018-04-16)
        ^^^^^^^^^^^^^^^^^^
        
        Abandoned version, please use 0.7.0 instead.
        
        0.6.3 (2018-04-08)
        ^^^^^^^^^^^^^^^^^^
        
        * Added aiohttp support
        * Added support for calling ``create()`` on model instances (Contributed by Kinware in #178 #180)
        * Fixed ``get()`` by string, and misc environment issues (Contributed by Tony Wang in #191 193 #183 #184)
        
        0.6.2 (2018-03-24)
        ^^^^^^^^^^^^^^^^^^
        
        * Fixed SQLAlchemy prefetch issue (#141)
        * Fixed issue that mixin class on Model not working (#174)
        * Added more documentation (Thanks Olaf Conradi for reviewing)
        
        0.6.1 (2018-03-18)
        ^^^^^^^^^^^^^^^^^^
        
        * Fixed ``create`` and ``drop`` for ``Enum`` type (#160)
        * A bit more documentation (#159)
        
        0.6.0 (2018-03-14)
        ^^^^^^^^^^^^^^^^^^
        
        * [Breaking] API Refactored, ``Pool`` replaced with ``Engine``
        
          * New API ``Engine`` replaced asyncpg ``Pool`` (#59)
          * Supported different dialects, theoretically
          * Used aiocontextvars_ instead of builtin task local (#89)
        * [Breaking] Fixed query API with ``multiparams`` (executemany) to return correctly (#20)
        * [Breaking] The query methods no longer accept the parameter ``bind``
        * [Breaking] ``Gino`` no longer exposes ``postgresql`` types
        * Added ``echo`` on engine (#142)
        * Added tests to cover 80% of code
        * Added ``gino`` extension on ``SchemaItem`` for ``create_all`` and so on (#76 #106)
        * Added ``gino`` extension on model classes for ``create()`` or ``drop()``
        * Added ``_update_request_cls`` on ``CRUDModel`` (#147)
        * Rewrote the documentation (#146)
        
        .. _aiocontextvars: https://github.com/fantix/aiocontextvars
        
        
        GINO 0.5
        --------
        
        This is also version 1.0 beta 1.
        
        0.5.8 (2018-02-14)
        ^^^^^^^^^^^^^^^^^^
        
        * Preparing for 0.6.0 which will be a breaking release
        * Fixed wrong value of ``Enum`` in creation (Contributed by Sergey Kovalev in #126)
        
        0.5.7 (2017-11-24)
        ^^^^^^^^^^^^^^^^^^
        
        This is an emergency fix for 0.5.6.
        
        * Fixed broken lazy connection (Contributed by Ádám Barancsuk in #114)
        * Added ``Model.outerjoin``
        
        0.5.6 (2017-11-23)
        ^^^^^^^^^^^^^^^^^^
        
        * Changed to use unnamed statement when possible (#80 #90)
        * Added more example (Contributed by Kentoseth in #109)
        * Added ``Model.join`` and made ``Model`` selectable (Contributed by Ádám Barancsuk in #112 #113)
        
        0.5.5 (2017-10-18)
        ^^^^^^^^^^^^^^^^^^
        
        * Ensured clean connection if transaction acquire fails (Contributed by Vladimir Goncharov in #87)
        * Added ability to reset local storage (#84)
        * Fixed bug in JSON property update
        * Added update chaining feature
        
        0.5.4 (2017-10-04)
        ^^^^^^^^^^^^^^^^^^
        
        * Updated example (Contributed by Kinware in #75)
        * Added ``Model.insert`` (Contributed by Neal Wang in #63)
        * Fixed issue that non-lazy acquiring fails dirty (#79)
        
        0.5.3 (2017-09-23)
        ^^^^^^^^^^^^^^^^^^
        
        * Fixed ``no module named cutils`` error (Contributed by Vladimir Goncharov in #73)
        
        0.5.2 (2017-09-10)
        ^^^^^^^^^^^^^^^^^^
        
        * Added missing driver name on dialect (#67)
        * Fixed dialect to support native decimal type (#67)
        
        0.5.1 (2017-09-09)
        ^^^^^^^^^^^^^^^^^^
        
        This is an emergency fix for 0.5.0.
        
        * Reverted the extension, back to pure Python (#60)
        * Used SQLAlchemy ``RowProxy``
        * Added ``first_or_404``
        * Fixed bug that ``GinoPool`` cannot be inherited
        
        0.5.0 (2017-09-03)
        ^^^^^^^^^^^^^^^^^^
        
        * [Breaking] Internal refactor: extracted and isolated a few modules, partially rewritten
        
          * Extracted CRUD operations
          * Core operations are moved to ``dialect`` and execution context
          * Removed ``guess_model``, switched to explicit execution options
          * Turned ``timeout`` parameter to an execution option
          * Extracted ``pool``, ``connection`` and ``api`` from ``asyncpg_delegate``
        * Added support for SQLAlchemy execution options, and a few custom options
        * [Breaking] Made `Model.select` return rows by default (#39)
        * Moved `get_or_404` to extensions (#38)
        * Added iterator on model classes (#43)
        * Added Tornado extension (Contributed by Vladimir Goncharov)
        * Added `Model.to_dict` (#47)
        * Added an extension module to update `asyncpg.Record` with processed results
        
        
        Early Development Releases
        --------------------------
        
        Considered as alpha releases.
        
        
        0.4.1 (2017-08-20)
        ^^^^^^^^^^^^^^^^^^
        
        * Support ``select`` on model instance
        
        0.4.0 (2017-08-15)
        ^^^^^^^^^^^^^^^^^^
        
        * Made ``get_or_404`` more friendly when Sanic is missing (Contributed by Neal Wang in #23 #31)
        * Delegated ``sqlalchemy.__all__`` (Contributed by Neal Wang in #10 #33)
        * [Breaking] Rewrote JSON/JSONB support (#29)
        * Added ``lazy`` parameter on ``db.acquire`` (Contributed by Binghan Li in #32)
        * Added Sanic integration (Contributed by Binghan Li, Tony Wang in #30 #32 #34)
        * Fixed ``iterate`` API to be compatible with asyncpg (#32)
        * Unified exceptions
        * [Breaking] Changed ``update`` API (#29)
        * Bug fixes
        
        0.3.0 (2017-08-07)
        ^^^^^^^^^^^^^^^^^^
        
        * Supported ``__table_args__`` (#12)
        * Introduced task local to manage connection in context (#19)
        * Added ``query.gino`` extension for in-place execution
        * Refreshed README (#3)
        * Adopted PEP 487 (Contributed by Tony Wang in #17 #27)
        * Used ``weakref`` on ``__model__`` of table and query (Contributed by Tony Wang)
        * Delegated asyncpg ``timeout`` parameter (Contributed by Neal Wang in #16 #22)
        
        0.2.3 (2017-08-04)
        ^^^^^^^^^^^^^^^^^^
        
        * Supported any primary key (Contributed by Tony Wang in #11)
        
        0.2.2 (2017-08-02)
        ^^^^^^^^^^^^^^^^^^
        
        * Supported SQLAlchemy result processor
        * Added rich support on JSON/JSONB
        * Bug fixes
        
        0.2.1 (2017-07-28)
        ^^^^^^^^^^^^^^^^^^
        
        * Added ``update`` and ``delete`` API
        
        0.2.0 (2017-07-28)
        ^^^^^^^^^^^^^^^^^^
        
        * Changed API, no longer reuses asyncpg API
        
        0.1.1 (2017-07-25)
        ^^^^^^^^^^^^^^^^^^
        
        * Added ``db.bind``
        * API changed: parameter ``conn`` renamed to optional ``bind``
        * Delegated asyncpg Pool with ``db.create_pool``
        * Internal enhancement and bug fixes
        
        0.1.0 (2017-07-21)
        ^^^^^^^^^^^^^^^^^^
        
        * First release on PyPI.
        
Keywords: orm asyncio sqlalchemy asyncpg python3 sanic aiohttp tornado
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Natural Language :: English
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
