GINO Is Not ORM - a Python asyncio ORM on SQLAlchemy core.

GINO

PyPI Release Version PyPI Monthly Downloads GitHub Workflow Status for CI Codacy Code Quality Codacy coverage

GINO - GINO Is Not ORM - is a lightweight asynchronous ORM built on top of SQLAlchemy core for Python asyncio. GINO 1.0 supports only PostgreSQL with asyncpg.

  • Free software: BSD license
  • Requires: Python 3.5
  • GINO is developed proudly with PyCharm .

Home

python-gino.org

Documentation

Installation

$ pip install gino

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 SQLAlchemy ecosystem, e.g. Alembic for migration
  • Community support for Starlette/FastAPI, aiohttp, Sanic, Tornado and Quart
  • Rich PostgreSQL JSONB support
Comments
  • mysql support

    mysql support

    A workable version based on master before baked queries.

    It's a "painful" journey patching the existing system.

    The main pain points:

    • MySQL doesn't support RETURNING
    • aiomysql doesn't support PREPARE
    • Syntax differences
    • Hard to tweak current test cases to satisfy both MySQL and PostgreSQL. I ended up having a new mysql_tests suite after spending too much time to make it compatible and failed.

    The code is structured catering for PostgreSQL. It'll be easier if we have a generic implementation in 2.0 integrating with other databases like SQLite

    Refs #381

  • How to set up quart and Gino

    How to set up quart and Gino

    • GINO version: 0.8.3
    • Python version: 3.7
    • asyncpg version: 0.19.0
    • aiocontextvars version: 0.2.2
    • PostgreSQL version: 11

    Description

    I want to use gino as an orm with quart, but i cant get it to connect together.... most of the time i get : Gino engine is not initialized. when i try to acess the db api when the server is running.

    The database tables were created but when i try to insert , i get this. and nothing seem to work.

    What I Did

    below is how i try to connect it

    from config import DevelopmentConfig
    from quart import Quart
    import asyncio
    from gino import Gino
    
    app = Quart(__name__)
    
    app.config.from_object(DevelopmentConfig)
    db = Gino()
    from app.views import deep, neutral
    
    app.register_blueprint(deep)
    app.register_blueprint(neutral)
    
    async def main():
        await db.set_bind(DevelopmentConfig.DATABASE_URI)
        await db.gino.create_all()
    
    if __name__ == '__main__':
        app.run()
    asyncio.get_event_loop().run_until_complete(main())
    
    
    

    This is the error

    Running on http://127.0.0.1:5000 (CTRL + C to quit)
    [2019-10-11 16:52:12,978] Running on 127.0.0.1:5000 over http (CTRL + C to quit)
    [2019-10-11 16:52:20,575] ERROR in app: Exception on request GET /telegram/messages/fetch
    Traceback (most recent call last):
      File "/home/lekan/Documents/workspace/telegram-flask/lib/python3.7/site-packages/quart/app.py", line 1524, in handle_request
        return await self.full_dispatch_request(request_context)
      File "/home/lekan/Documents/workspace/telegram-flask/lib/python3.7/site-packages/quart/app.py", line 1546, in full_dispatch_request
        result = await self.handle_user_exception(error)
      File "/home/lekan/Documents/workspace/telegram-flask/lib/python3.7/site-packages/quart/app.py", line 957, in handle_user_exception
        raise error
      File "/home/lekan/Documents/workspace/telegram-flask/lib/python3.7/site-packages/quart/app.py", line 1544, in full_dispatch_request
        result = await self.dispatch_request(request_context)
      File "/home/lekan/Documents/workspace/telegram-flask/lib/python3.7/site-packages/quart/app.py", line 1592, in dispatch_request
        return await handler(**request_.view_args)
      File "/home/lekan/Documents/workspace/telegram-flask/deepview-telegram/app/views.py", line 72, in fetch
        msgs = await client.messages(limit=500)
      File "/home/lekan/Documents/workspace/telegram-flask/deepview-telegram/app/request.py", line 50, in messages
        msg = await DbMessage.get_messages(message_id=message.id)
      File "/home/lekan/Documents/workspace/telegram-flask/lib/python3.7/site-packages/gino/api.py", line 135, in first
        return await self._query.bind.first(self._query, *multiparams,
      File "/home/lekan/Documents/workspace/telegram-flask/lib/python3.7/site-packages/gino/api.py", line 501, in __getattribute__
        raise self._exception
    gino.exceptions.UninitializedError: Gino engine is not initialized.
    

    I also tried to do this in my views:

    @app.before_serving
    async def main():
        await db.set_bind(DevelopmentConfig.DATABASE_URI)
        await db.gino.create_all()
    
    asyncio.get_event_loop().run_until_complete(main())
    
    

    but i get the same error.

    Please i'd appreciate if you could help on how to connect and do db operations successfuly.

    Thanks.

  • What about relationship?

    What about relationship?

    ~Honestly I have no idea yet.~

    Update:

    GINO now has a loader mechanism to load a result matrix into objects on need, please see examples below. It allows relationship be implemented in a primitive way. Next, we'll try to introduce some high level relationship encapsulation.

  • "Another operation is in progress" error when using transactions and asyncio.gather

    Hello! When i need to make several operations in parallel with db i'm using asyncio.gather with task and transaction inside it, but i have found that in GINO it does not work correctly - throws an error asyncpg.exceptions._base.InterfaceError: cannot perform operation: another operation is in progress

    How to reproduce it:

        async def t():
            async with db.transaction():
                await Model.query.gino.first()
    
        await asyncio.gather(*[t() for i in range(5)])
    

    If i will place db.acquire before db.transaction it does not change anything.

    I think that problem is that there must be new real connection and transaction in it when using asyncio.gather

    stacktrace

     await Model.query.gino.first()
      File "venv/project/lib/python3.7/site-packages/gino/api.py", line 135, in first
        **params)
      File "venv/project/lib/python3.7/site-packages/gino/engine.py", line 681, in first
        return await conn.first(clause, *multiparams, **params)
      File "venv/project/lib/python3.7/site-packages/gino/engine.py", line 336, in first
        return await result.execute(one=True)
      File "venv/project/lib/python3.7/site-packages/gino/dialects/base.py", line 207, in execute
        context.statement, context.timeout, args, 1 if one else 0)
      File "venv/project/lib/python3.7/site-packages/gino/dialects/asyncpg.py", line 175, in async_execute
        query, executor, timeout)
      File "venv/project/lib/python3.7/site-packages/asyncpg/connection.py", line 1400, in _do_execute
        stmt = await self._get_statement(query, None)
      File "venv/project/lib/python3.7/site-packages/asyncpg/connection.py", line 323, in _get_statement
        statement = await self._protocol.prepare(stmt_name, query, timeout)
      File "asyncpg/protocol/protocol.pyx", line 165, in prepare
      File "asyncpg/protocol/protocol.pyx", line 675, in asyncpg.protocol.protocol.BaseProtocol._check_state
    asyncpg.exceptions._base.InterfaceError: cannot perform operation: another operation is in progress
    
    • GINO version: 0.7.5
    • Python version: 3.7.0
    • asyncpg version: 0.17.0
    • PostgreSQL version: 9.6.9
    • Quart version 0.6.4
  • Add support for inline model constraints

    Add support for inline model constraints

    Currently there are two ways to specify constraints and indexes covering multiple columns.

    1. Define the constraint or index outside the model class
    2. Define the constraint or index in the model class using the __table_args__ attribute

    The first option is (IMO) not as clean as keeping all details about the model inside the class. The second option works, but looks a bit ugly (again, IMO).

    This PR adds a third alternative for specifying constraints and indexes "inline" (as sqlalchemy docs call it).

    There are no tests yet (wanted to see if the feature is appropriate for inclusion or not first), but I guess adding something in test_declarative.py would be appropriate. Maybe define a model like the one in the docs in this PR, and then verify that the constraint is enforced (i.e insert same value twice).

    Thoughts?

  • ModelLoader Columns objects support in column loader

    ModelLoader Columns objects support in column loader

    We need to support column names in ModelLoader also as Column objects, to correctly fill model fields in complex aliased queries. Now Loader can't handle them properly, because part of model names can overlap, like id, name etc... and loader iterates only over their names when filling values.

  • Manage local storage inherit behavior

    Manage local storage inherit behavior

    Hello!

    Is there a reason to do task.task_local = get_local() or {} instead of just task.task_local = {}? Because now if you spawn a task inside of another task, you get the same local context for both tasks ant this may cause very strange errors.

  • Error when jsonify query result

    Error when jsonify query result

    code:

    from sanic import response
    ...
        u1 = await User.create(nickname='fantixd')
        u2 = await User.get(u1.id)
    
        return response.json(u2)
    

    Error:

      File "/usr/local/lib/python3.6/site-packages/sanic/response.py", line 246, in json
        return HTTPResponse(json_dumps(body, **kwargs), headers=headers,
    OverflowError: Maximum recursion level reached
    
    
  • Experiment with trio support

    Experiment with trio support

    I tried to make this run on top of the trio event loop. In a way, gino is uniquely positioned to support other event loops because it's dependency on asyncio is so light. It's basically just timeouts and one `asyncio.Lock. The rest is cleanly encapsulated within the dialect implementation.

    So this does two things:

    • It introduced a simple "backend" class, to customize which Lock is used, and how timeouts work.
    • It uses sniffio to automatically pick the right backend based on the loop used.
    • It ads a dialect based on riopg, which is psycopg2 on trio.

    At it stands, it runs the Showcase example successfully up until the last part where gino.iterate() is used. I stumbled there because gino core uses prepared statements here, and psycopg2 does not support them. Or at least that was my impression.

    This is absolutely not merge-ready, but I did want to ask for some feedback, in particular if this is something that you see gino supporting.

  • Transaction context fails to relay the original exception if rollback raises.

    Transaction context fails to relay the original exception if rollback raises.

    • GINO version: 0.7.5
    • Python version: 3.5.3
    • asyncpg version: 0.17.0
    • aiocontextvars version: 0.1.2
    • PostgreSQL version: 9.6.9

    Description

    I'm using PostgreSQL with serializable isolation level transactions. I've tried to write a decorator to make Python object functions retry the whole transaction whenever a transaction is cancelled by a serialization conflict (or a transient database disconnect).

    What I Did

    I wrote this code for a decorator(that depends on a specific hierarchies on for the class of the object decorated, but that's a detail):

    from asyncpg.exceptions import SerializationError, PostgresConnectionError
    
    def serializable_transaction(num_retries=100, connection_error_delay=10):
        def decorate(fn):
            async def wrapper(self, *args, **kwargs):
                retries = num_retries
                while True:
                    try:
                        async with self.server.db.transaction(isolation='serializable'):
                            return await fn(self, *args, **kwargs)
                    except SerializationError:
                        self.logger.warning(
                            F('Transaction serialization failure, {#E:{}#} retries left.', retries),
                            exc_info=True)
                        retries -= 1
                        if retries <= 0:
                            raise
                    except PostgresConnectionError:
                        self.logger.warning(
                            F('Database connection failure, {#E:{}#} retries left.', retries),
                            exc_info=True)
                        retries -= 1
                        if retries <= 0:
                            raise
                        await self.sleep(connection_error_delay)
    
            return wrapper
    
        return decorate
    

    The original coroutine is awaited for within an async with context for the transaction. If a SerializationError is raised, the whole thing is retried.

    But this is not working as intended. The reason for that being the case lies in here:

    https://github.com/fantix/gino/blob/d074dc4304cb050ba5b49a599b59af1d0d6c8e64/gino/transaction.py#L178

    When a SerializationError bubbles up, the context tries to roll the transaction back. But the transaction has already been aborted, and rolling back fails with a different exception, which is the one that comes out of the context manager code.

    At that point the caller has lost the information about what the original exception was, and thus my decorator doesn't work.

    A possible approach would be to just log any exception raised by the statement in the link, and continue to raise the original exception.

  • Fix issue with concurrent contextual stack modification

    Fix issue with concurrent contextual stack modification

    We are using gino in production, and we had a lot of unexpected exceptions from asynpg with a message:

    asyncpg.exceptions._base.InterfaceError: cannot perform operation: another operation is in progress
    

    The problem was, that these exceptions were unpredictable and we had no idea what we a doing wrong.

    Basically, we a using asyncio based web framework and we had a lot of code patterns like this:

    db = Gino()
    
    def worker(entity):
         async with db.acquire(reuse=False):
              ... # do some database queries based on entity
    
    def main():
         async with db.acquire(reuse=False):
              entities = await Entity.query.gino.all()
              tasks = [create_task(worker(entity)) for entity in entities)]
              # do some useful thing concurrently to started tasks
              result = await Entity.query.where(...).gino.all()  # make another query to db
              await gather(*tasks)
    

    And sometimes we had an exception at this place:

    result = await Entity.query.where(...).gino.all()  # make another query to db
    

    This exception cancels one of the running worker tasks.

    Today after hours of debugging I have found the root cause of this issue🥳

    The problem was with the concurrent _ContextualStack._ctx value modification. When we are creating a new asyncio task we copy current contextvars to the created task. In a case when there are reusable connections it will copy deque of those connections to the context of a child task. In a case when we acquire a new DB connection in a child task it will modify the deque of reusable connection which is a completely same deque that are using at main task.

    I hope you understood the issue)

    The solution that I used is to use an immutable single linked list as a contextual stack, in such case concurrent tasks won't mutate the stack of each other.

    @fantix It will be great for me and my team if you can review this PR and release new version of a gino which will include this fix, so we can remove the workaround from our code that we currently have.

  • TypeError: expected str, got int

    TypeError: expected str, got int

    Describe the bug A TypeError when passed integer to literal()

    To Reproduce

    import os
    import asyncio
    from gino import Gino
    from sqlalchemy import Integer
    
    db = Gino()
    
    async def main():
        await db.set_bind('FILLME')
    
        query = db.select([ db.literal(1, type_=Integer).label('test') ], bind=db)
    
        print(await query.gino.all())
    
        await db.pop_bind().close()
    
    
    asyncio.get_event_loop().run_until_complete(main())
    

    Expected result Expect to get an equivalent of this:

    database=> select 1::int as test;
     test 
    ------
        1
    (1 row)
    

    Actual result

    Traceback (most recent call last):
      File "asyncpg/protocol/prepared_stmt.pyx", line 155, in asyncpg.protocol.protocol.PreparedStatementState._encode_bind_msg
      File "asyncpg/protocol/codecs/base.pyx", line 193, in asyncpg.protocol.protocol.Codec.encode
      File "asyncpg/protocol/codecs/base.pyx", line 104, in asyncpg.protocol.protocol.Codec.encode_scalar
      File "asyncpg/pgproto/./codecs/text.pyx", line 29, in asyncpg.pgproto.pgproto.text_encode
      File "asyncpg/pgproto/./codecs/text.pyx", line 12, in asyncpg.pgproto.pgproto.as_pg_string_and_size
    TypeError: expected str, got int
    
    The above exception was the direct cause of the following exception:
    
    Traceback (most recent call last):
      File "test_gino.py", line 18, in <module>
        asyncio.get_event_loop().run_until_complete(main())
      File "lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
        return future.result()
      File "test_gino.py", line 13, in main
        print(await query.gino.all())
      File "lib/python3.9/site-packages/gino/api.py", line 127, in all
        return await self._query.bind.all(self._query, *multiparams, **params)
      File "lib/python3.9/site-packages/gino/api.py", line 472, in all
        return await self.bind.all(clause, *multiparams, **params)
      File "lib/python3.9/site-packages/gino/engine.py", line 740, in all
        return await conn.all(clause, *multiparams, **params)
      File "lib/python3.9/site-packages/gino/engine.py", line 316, in all
        return await result.execute()
      File "lib/python3.9/site-packages/gino/dialects/base.py", line 214, in execute
        rows = await cursor.async_execute(
      File "lib/python3.9/site-packages/gino/dialects/asyncpg.py", line 184, in async_execute
        result, stmt = await getattr(conn, "_do_execute")(query, executor, timeout)
      File "lib/python3.9/site-packages/asyncpg/connection.py", line 1711, in _do_execute
        result = await executor(stmt, None)
      File "asyncpg/protocol/protocol.pyx", line 183, in bind_execute
      File "asyncpg/protocol/prepared_stmt.pyx", line 171, in asyncpg.protocol.protocol.PreparedStatementState._encode_bind_msg
    asyncpg.exceptions.DataError: invalid input for query argument $1: 1 (expected str, got int)
    
    

    Environment (please complete the following information):

    • GINO: 1.0.1
    • SQLAlchemy: 1.3.24
    • Asyncpg: 0.24
  • Version bump of SQLAlchemy 1.4

    Version bump of SQLAlchemy 1.4

    Is your feature request related to a problem? Please describe. SQLAlchemy was launched on March 2021

    Describe the solution you'd like Gino should be able to support 1.4 version of SQLAlchemy.

  • gino does not work correctly with enum types in postgresql

    gino does not work correctly with enum types in postgresql

    Describe the bug

    I'm trying to use gino in postgres with simple model with enum column type. It seems like enum is not fully supported and it behaves really strange in several cases:

    1. when using gino Enum type in where filters, asyncpg.exceptions.InternalServerError: cache lookup failed for type 16453 error occurs
    2. when using postgresql Enum and running db.gino.create_all(), asyncpg.exceptions.UndefinedObjectError: type "test-schema.enum1" does not exist error occurs

    To Reproduce

    The full example is in my repo: https://github.com/zerlok/python-bugs/tree/gino/enum-usage

    import asyncio
    import enum
    import os
    import typing as t
    
    import gino
    import pytest
    import sqlalchemy as sa
    from sqlalchemy.dialects.postgresql import ENUM as PostgresEnum
    
    DB_SCHEMA = os.getenv("SCHEMA")
    DB = gino.Gino(schema=DB_SCHEMA)
    
    
    class Enum1(enum.Enum):
        VAL1 = enum.auto()
        VAL2 = enum.auto()
    
    
    class Enum2(enum.Enum):
        VAL3 = enum.auto()
        VAL4 = enum.auto()
        VAL5 = enum.auto()
    
    
    @pytest.mark.asyncio
    class TestGinoEnum:
    
        @pytest.fixture(scope="session")
        async def engine(self):
            async with DB.with_bind(os.getenv("DATABASE")) as engine:
                yield engine
    
        @pytest.fixture(scope="session")
        def db_model(self, gino_enum_type, engine) -> gino.Gino.Model:
            if gino_enum_type == "postgres":
                class Foo(DB.Model):
                    __tablename__ = "foo"
    
                    id = DB.Column(DB.Integer(), primary_key=True)
    
                    # causes asyncpg.exceptions.UndefinedObjectError: type "test.enum1" does not exist
                    enum_field1 = DB.Column(PostgresEnum(Enum1, inherit_schema=True), default=Enum1.VAL1, nullable=False)
                    enum_field2 = DB.Column(PostgresEnum(Enum2, inherit_schema=True), default=Enum2.VAL3, nullable=False)
    
            elif gino_enum_type is None:
                class Foo(DB.Model):
                    __tablename__ = "foo"
    
                    id = DB.Column(DB.Integer(), primary_key=True)
    
                    # no exception
                    enum_field1 = DB.Column(DB.Enum(Enum1, inherit_schema=True), default=Enum1.VAL1, nullable=False)
                    enum_field2 = DB.Column(DB.Enum(Enum2, inherit_schema=True), default=Enum2.VAL3, nullable=False)
    
            else:
                raise ValueError("unknown gino type", gino_enum_type)
    
            return Foo
    
        @pytest.fixture()
        async def clean_database(self, gino_enum_type, gino_create_enum_type_manually, engine, db_model):
            await DB.gino.drop_all()
    
            if DB_SCHEMA:
                await engine.status(f"""drop schema if exists \"{DB_SCHEMA}\" cascade""")
                await engine.status(f"""create schema if not exists \"{DB_SCHEMA}\"""")
    
            if gino_create_enum_type_manually:
                def quote_value(value: t.Union[Enum1, Enum2]) -> str:
                    return f"'{value.name}'"
    
                async def create_enum(e: t.Union[t.Type[Enum1], t.Type[Enum2]]) -> None:
                    if DB_SCHEMA:
                        enum_type = f"\"{DB_SCHEMA}\".{e.__name__.lower()}"
                    else:
                        enum_type = f"{e.__name__.lower()}"
    
                    await engine.status(f"""
                        create type {enum_type} as enum ({",".join(quote_value(v) for v in e)})
                    """)
    
                await create_enum(Enum1)
                await create_enum(Enum2)
    
            else:
                # hope that enum types will be added automatically with `create_all` .
                pass
    
            await DB.gino.create_all()
    
        async def test_enum_types_removal(self, engine, clean_database) -> None:
            await DB.gino.drop_all()
            assert (await self.__get_enum_info_from_database(engine)) == []
    
        async def test_enum_type_creation(self, engine, clean_database) -> None:
            assert (await self.__get_enum_info_from_database(engine)) == sorted(
                (DB_SCHEMA or "public", enum_type.__name__.lower(), val.name)
                for enum_type in (Enum1, Enum2)
                for val in enum_type
            )
    
        @pytest.mark.parametrize("n", (0, 1, 2))
        async def test_enum_type_filter(self, engine, clean_database, db_model, n) -> None:
            # when n == 2, `the asyncpg.exceptions.InternalServerError: cache lookup failed for type 16453` occurs
            assert (await asyncio.gather(*(
                self.__get_bars(engine, db_model)
                for i in range(n)
            ))) == [[] for i in range(n)]
    
        async def __get_bars(self, engine: gino.GinoEngine, db_model: gino.Gino.Model) -> [object]:
            val1 = await engine.all(db_model.query.where(db_model.enum_field1 == Enum1.VAL1))
            val4 = await engine.all(
                sa.select([db_model.id]).select_from(db_model).where(db_model.enum_field2 == Enum2.VAL4))
    
            return [*val1, *val4]
    
        async def __get_enum_info_from_database(self, engine: gino.GinoEngine) -> t.Sequence[t.Tuple[str, str, str]]:
            return await engine.all("""
                select n.nspname as enum_schema, t.typname as enum_name, e.enumlabel as enum_value
                from pg_type t
                join pg_enum e on t.oid = e.enumtypid
                join pg_catalog.pg_namespace n ON n.oid = t.typnamespace
                order by enum_schema, enum_name, enum_value
            """)
    

    Expected result

    I want all my test runs to finish without described exceptions. See README: https://github.com/zerlok/python-bugs/tree/gino/enum-usage#troubles-with-gino-sqlalchemy-postgres-enum

    Actual result

    For 1 case

    FAILED tests/test_gino.py::TestGinoEnum::test_enum_type_filter[2] - asyncpg.exceptions.InternalServerError: cache lookup failed for type 16453
    

    For 2 case

    ERROR tests/test_gino.py::TestGinoEnum::test_enum_types_removal - asyncpg.exceptions.UndefinedObjectError: type "test-schema.enum1" does not exist
    ERROR tests/test_gino.py::TestGinoEnum::test_enum_type_creation - asyncpg.exceptions.UndefinedObjectError: type "test-schema.enum1" does not exist
    ERROR tests/test_gino.py::TestGinoEnum::test_enum_type_filter[0] - asyncpg.exceptions.UndefinedObjectError: type "test-schema.enum1" does not exist
    ERROR tests/test_gino.py::TestGinoEnum::test_enum_type_filter[1] - asyncpg.exceptions.UndefinedObjectError: type "test-schema.enum1" does not exist
    ERROR tests/test_gino.py::TestGinoEnum::test_enum_type_filter[2] - asyncpg.exceptions.UndefinedObjectError: type "test-schema.enum1" does not exist
    

    Environment (please complete the following information):

    asyncpg==0.25.0; python_version >= "3.5" and python_version < "4.0" and python_full_version >= "3.6.0"
    atomicwrites==1.4.0; python_version >= "3.7" and python_full_version < "3.0.0" and sys_platform == "win32" or sys_platform == "win32" and python_version >= "3.7" and python_full_version >= "3.4.0"
    attrs==21.4.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7"
    click==8.1.3; python_version >= "3.7"
    colorama==0.4.4; python_version >= "3.7" and python_full_version < "3.0.0" and sys_platform == "win32" and platform_system == "Windows" or sys_platform == "win32" and python_version >= "3.7" and python_full_version >= "3.5.0" and platform_system == "Windows"
    gino==1.0.1; python_version >= "3.5" and python_version < "4.0"
    iniconfig==1.1.1; python_version >= "3.7"
    packaging==21.3; python_version >= "3.7"
    pluggy==1.0.0; python_version >= "3.7"
    py==1.11.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7"
    pyparsing==3.0.9; python_full_version >= "3.6.8" and python_version >= "3.7"
    pytest-asyncio==0.18.3; python_version >= "3.7"
    pytest==7.1.2; python_version >= "3.7"
    sqlalchemy==1.3.24; python_version >= "3.5" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.5" and python_version < "4.0" and python_full_version >= "3.4.0"
    tomli==2.0.1; python_version >= "3.7"
    wait-for-it==2.2.1; python_version >= "3.7"
    

    postgres: 11.10

    Additional context

    I described a full info in my repo (it was easier for my) and I provided the full environment (docker image and docker-compose) to reproduce this bug, look at my repo: https://github.com/zerlok/python-bugs/tree/gino/enum-usage.

  • DB initialisation with mangum

    DB initialisation with mangum

    We are trying to deploy a FastAPI + starlette + gino-starlette + async psql microservice in AWS lambda using mangum handler, seems init_db is not allowing the lambda to start, is that Gino supports aws lambda deployment ?

  • TypeError while trying to initialize Gino db with MySQL

    TypeError while trying to initialize Gino db with MySQL

    TypeError while trying to initialize Gino db with MySQL

    To Reproduce

    from gino_starlette import Gino
    DATABASE_URL = f"mysql+aiomysql://{DATABASE_USER}:{DATABASE_PASSWORD}@{DATABASE_HOST}:{DATABASE_PORT}/{DATABASE_NAME}"
    
    db = Gino(
        dsn=DATABASE_URL,
        echo=True
    )
    

    Actual result

    Cannot connect to the database; max retries reached.
    ERROR:    Traceback (most recent call last):
      File "...projects/.../.venv39/lib/python3.9/site-packages/starlette/routing.py", line 621, in lifespan
        async with self.lifespan_context(app):
      File "...projects/.../.venv39/lib/python3.9/site-packages/starlette/routing.py", line 518, in __aenter__
        await self._router.startup()
      File "...projects/.../.venv39/lib/python3.9/site-packages/starlette/routing.py", line 598, in startup
        await handler()
      File "...projects/.../.venv39/lib/python3.9/site-packages/gino_starlette.py", line 177, in startup
        await self.set_bind(
      File "...projects/.../.venv39/lib/python3.9/site-packages/gino_starlette.py", line 226, in set_bind
        return await super().set_bind(bind, loop=loop, **kwargs)
      File "...projects/.../.venv39/lib/python3.9/site-packages/gino/api.py", line 427, in set_bind
        bind = await create_engine(bind, loop=loop, bakery=self._bakery, **kwargs)
      File "...projects/.../.venv39/lib/python3.9/site-packages/gino/strategies.py", line 68, in create
        raise TypeError(
    TypeError: Invalid argument(s) 'min_size','max_size' sent to create_engine(), using configuration AiomysqlDialect/GinoEngine.  Please check that the keyword arguments are appropriate for this combination of components.
    
    

    Environment:

    • GINO: 1.1.b2
    • Other: Python 3.9
  • Gino 1.1b2 doesn't work on Python 3.10.2 and aiomysql

    Gino 1.1b2 doesn't work on Python 3.10.2 and aiomysql

    Gino 1.1b2 doesn't work on Python 3.10.2 and aiomysql

    To Reproduce

    from gino_starlette import Gino
    DATABASE_URL = f"mysql+aiomysql://{DATABASE_USER}:{DATABASE_PASSWORD}@{DATABASE_HOST}:{DATABASE_PORT}/{DATABASE_NAME}"
    
    db = Gino(
        dsn=DATABASE_URL,
        echo=True
    )
    

    Actual result

    TypeError: As of 3.10, the *loop* parameter was removed from Condition() since it is no longer necessary
    
    

    Environment:

    • GINO: 1.1.b2
    • Other: Python 3.10.2

    Possible reason: incompatible versions of asyncio\python and aiomysql

Asynchronous interface for peewee ORM powered by asyncio

peewee-async Asynchronous interface for peewee ORM powered by asyncio. Important notes Since version 0.6.0a only peewee 3.5+ is supported If you still

Nov 29, 2022
Motor - the async Python driver for MongoDB and Tornado or asyncio
Motor - the async Python driver for MongoDB and Tornado or asyncio

Motor Info: Motor is a full-featured, non-blocking MongoDB driver for Python Tornado and asyncio applications. Documentation: Available at motor.readt

Dec 3, 2022
A fast PostgreSQL Database Client Library for Python/asyncio.
A fast PostgreSQL Database Client Library for Python/asyncio.

asyncpg -- A fast PostgreSQL Database Client Library for Python/asyncio asyncpg is a database interface library designed specifically for PostgreSQL a

Nov 29, 2022
Motor - the async Python driver for MongoDB and Tornado or asyncio
Motor - the async Python driver for MongoDB and Tornado or asyncio

Motor Info: Motor is a full-featured, non-blocking MongoDB driver for Python Tornado and asyncio applications. Documentation: Available at motor.readt

Feb 6, 2021
Redis client for Python asyncio (PEP 3156)

Redis client for Python asyncio. Redis client for the PEP 3156 Python event loop. This Redis library is a completely asynchronous, non-blocking client

Dec 2, 2022
An asyncio compatible Redis driver, written purely in Python. This is really just a pet-project for me.
An asyncio compatible Redis driver, written purely in Python. This is really just a pet-project for me.

asyncredis An asyncio compatible Redis driver. Just a pet-project. Information asyncredis is, like I've said above, just a pet-project for me. I reall

Dec 25, 2021
A wrapper around asyncpg for use with sqlalchemy

asyncpgsa A python library wrapper around asyncpg for use with sqlalchemy Backwards incompatibility notice Since this library is still in pre 1.0 worl

Dec 3, 2022
aiopg is a library for accessing a PostgreSQL database from the asyncio

aiopg aiopg is a library for accessing a PostgreSQL database from the asyncio (PEP-3156/tulip) framework. It wraps asynchronous features of the Psycop

Dec 3, 2022
aiomysql is a library for accessing a MySQL database from the asyncio

aiomysql aiomysql is a "driver" for accessing a MySQL database from the asyncio (PEP-3156/tulip) framework. It depends on and reuses most parts of PyM

Nov 26, 2022
aioodbc - is a library for accessing a ODBC databases from the asyncio

aioodbc aioodbc is a Python 3.5+ module that makes it possible to access ODBC databases with asyncio. It relies on the awesome pyodbc library and pres

Dec 5, 2022
asyncio (PEP 3156) Redis support

aioredis asyncio (PEP 3156) Redis client library. Features hiredis parser Yes Pure-python parser Yes Low-level & High-level APIs Yes Connections Pool

Dec 2, 2022
CouchDB client built on top of aiohttp (asyncio)

aiocouchdb source: https://github.com/aio-libs/aiocouchdb documentation: http://aiocouchdb.readthedocs.org/en/latest/ license: BSD CouchDB client buil

Apr 5, 2022
asyncio compatible driver for elasticsearch

asyncio client library for elasticsearch aioes is a asyncio compatible library for working with Elasticsearch The project is abandoned aioes is not su

Sep 5, 2022
a small, expressive orm -- supports postgresql, mysql and sqlite
a small, expressive orm -- supports postgresql, mysql and sqlite

peewee Peewee is a simple and small ORM. It has few (but expressive) concepts, making it easy to learn and intuitive to use. a small, expressive ORM p

Nov 26, 2022
Async ORM based on PyPika

PyPika-ORM - ORM for PyPika SQL Query Builder The package gives you ORM for PyPika with asycio support for a range of databases (SQLite, PostgreSQL, M

Jun 4, 2022
MySQL database connector for Python (with Python 3 support)

mysqlclient This project is a fork of MySQLdb1. This project adds Python 3 support and fixed many bugs. PyPI: https://pypi.org/project/mysqlclient/ Gi

Nov 28, 2022
MySQL database connector for Python (with Python 3 support)

mysqlclient This project is a fork of MySQLdb1. This project adds Python 3 support and fixed many bugs. PyPI: https://pypi.org/project/mysqlclient/ Gi

Nov 28, 2022
Python interface to Oracle Database conforming to the Python DB API 2.0 specification.

cx_Oracle version 8.2 (Development) cx_Oracle is a Python extension module that enables access to Oracle Database. It conforms to the Python database

Nov 25, 2022
PubMed Mapper: A Python library that map PubMed XML to Python object

pubmed-mapper: A Python Library that map PubMed XML to Python object 中文文档 1. Philosophy view UML Programmatically access PubMed article is a common ta

Oct 27, 2022