encode / databases

Async database support for Python. 🗄
https://www.encode.io/databases/
BSD 3-Clause "New" or "Revised" License
3.85k stars 262 forks source link

OperationalError: (2013, 'Lost connection to MySQL server during query ([Errno 32] Broken pipe #486

Closed mmalka87 closed 2 years ago

mmalka87 commented 2 years ago

Python: 3.10 Databases: 0.5.5 Database backend: MySQL

getting this error after ~8 hours of service running:

asyncmy.errors.OperationalError: (2013, 'Lost connection to MySQL server during query ([Errno 32] Broken pipe)')

i am using Ormar as my ORM and databases to connect to my db (MySQL) and asyncmy as my driver. this is my code for the file base.py:

from databases import Database
from sqlalchemy import MetaData
from ormar import ModelMeta

database = Database(MYSQL_CONNECTION_PATH)
metadata = MetaData()

class MainMeta(ModelMeta):
    database = database
    metadata = metadata

and this is (part of) my code for the file core.py:

@database.transaction()
async def bulk_create_login_events(login_events):
    try:
        model_objects = []
        for login_event in login_events:
            model_objects.append(
                LoginEvent(...)  # this is an Ormar model i put data in
            )
        await LoginEvent.objects.bulk_create(model_objects)
    except Exception:
        raise

what am i missing? why do i get this error? do i need to reconnnect explicitly before every query? it says in your docs:

Databases handles database connection pooling and transaction management with minimal fuss. It'll automatically deal with acquiring and releasing connections to the pool as needed, and supports a simple transaction API that transparently handles the use of either transactions or savepoints.

full stack trace:


File "asyncmy/connection.pyx", line 578, in read_packet
File "asyncmy/connection.pyx", line 612, in _read_bytes
asyncmy.errors.OperationalError: (2013, 'Lost connection to MySQL server during query ([Errno 32] Broken pipe)')
return future.result()
File "/app/<redacted>/services/user_login_events/loader/__main__.py", line 15, in main
await load()
File "/app/<redacted>/services/user_login_events/loader/core.py", line 71, in load
await _load(consumer)
File "/home/user/.local/lib/python3.10/site-packages/<redacted>/utils/logging/helpers.py", line 56, in wrapper
return await func(*args, **kwargs)
File "/app/<redacted>/services/user_login_events/loader/core.py", line 52, in _load
await bulk_create_login_events(records)
File "/home/user/.local/lib/python3.10/site-packages/databases/core.py", line 384, in wrapper
async with self:
File "/home/user/.local/lib/python3.10/site-packages/databases/core.py", line 354, in __aenter__
await self.start()
File "/home/user/.local/lib/python3.10/site-packages/databases/core.py", line 396, in start
await self._transaction.start(
File "/home/user/.local/lib/python3.10/site-packages/databases/backends/asyncmy.py", line 236, in start
await self._connection._connection.begin()
File "asyncmy/connection.pyx", line 353, in begin
await self._waiter
File "/usr/local/lib/python3.10/asyncio/selector_events.py", line 918, in write
n = self._sock.send(data)
BrokenPipeError: [Errno 32] Broken pipe
(empty)
During handling of the above exception, another exception occurred:
(empty)
Traceback (most recent call last):
File "/usr/local/lib/python3.10/runpy.py", line 196, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/usr/local/lib/python3.10/runpy.py", line 86, in _run_code
exec(code, run_globals)
File "/app/<redacted>/services/user_login_events/loader/__main__.py", line 18, in <module>
asyncio.run(main())
File "/usr/local/lib/python3.10/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/usr/local/lib/python3.10/asyncio/base_events.py", line 641, in run_until_complete
Traceback (most recent call last):
File "asyncmy/connection.pyx", line 610, in asyncmy.connection.Connection._read_bytes
File "/usr/local/lib/python3.10/asyncio/streams.py", line 708, in readexactly
await self._wait_for_data('readexactly')
File "/usr/local/lib/python3.10/asyncio/streams.py", line 502, in _wait_for_data```
mmalka87 commented 2 years ago

in the meantime (until i get a reply) i tried this:

from contextlib import asynccontextmanager

database = Database(cfg.MYSQL_CONNECTION_PATH)

@asynccontextmanager
async def connect(transaction=False):
    async with database as _database:
        try:
            await _database.connect()
            if transaction:
                async with database.connection() as connection:
                    async with connection.transaction():
                        yield
            else:
                yield
        except Exception as exc:
            logger.exception('Failed to connect to db')
            raise
        finally:
            await database.disconnect()

will try to update here if this works

mmalka87 commented 2 years ago

for anyone landing here...i changed my backend engine to aiomysql (was asyncmy) and added this code:

try:
    await database.connect()
    ...  # my code
finally:
    await database.disconnect()