Загрузить файлы в «venv/Lib/site-packages/sqlalchemy/dialects/mysql»

This commit is contained in:
2026-07-02 20:21:49 +00:00
parent ff63216580
commit 233c686c4b
5 changed files with 4689 additions and 0 deletions

View File

@@ -0,0 +1,104 @@
# dialects/mysql/__init__.py
# Copyright (C) 2005-2026 the SQLAlchemy authors and contributors
# <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
# the MIT License: https://www.opensource.org/licenses/mit-license.php
# mypy: ignore-errors
from . import aiomysql # noqa
from . import asyncmy # noqa
from . import base # noqa
from . import cymysql # noqa
from . import mariadbconnector # noqa
from . import mysqlconnector # noqa
from . import mysqldb # noqa
from . import pymysql # noqa
from . import pyodbc # noqa
from .base import BIGINT
from .base import BINARY
from .base import BIT
from .base import BLOB
from .base import BOOLEAN
from .base import CHAR
from .base import DATE
from .base import DATETIME
from .base import DECIMAL
from .base import DOUBLE
from .base import ENUM
from .base import FLOAT
from .base import INTEGER
from .base import JSON
from .base import LONGBLOB
from .base import LONGTEXT
from .base import MEDIUMBLOB
from .base import MEDIUMINT
from .base import MEDIUMTEXT
from .base import NCHAR
from .base import NUMERIC
from .base import NVARCHAR
from .base import REAL
from .base import SET
from .base import SMALLINT
from .base import TEXT
from .base import TIME
from .base import TIMESTAMP
from .base import TINYBLOB
from .base import TINYINT
from .base import TINYTEXT
from .base import VARBINARY
from .base import VARCHAR
from .base import YEAR
from .dml import Insert
from .dml import insert
from .expression import match
from .mariadb import INET4
from .mariadb import INET6
# default dialect
base.dialect = dialect = mysqldb.dialect
__all__ = (
"BIGINT",
"BINARY",
"BIT",
"BLOB",
"BOOLEAN",
"CHAR",
"DATE",
"DATETIME",
"DECIMAL",
"DOUBLE",
"ENUM",
"FLOAT",
"INET4",
"INET6",
"INTEGER",
"INTEGER",
"JSON",
"LONGBLOB",
"LONGTEXT",
"MEDIUMBLOB",
"MEDIUMINT",
"MEDIUMTEXT",
"NCHAR",
"NVARCHAR",
"NUMERIC",
"SET",
"SMALLINT",
"REAL",
"TEXT",
"TIME",
"TIMESTAMP",
"TINYBLOB",
"TINYINT",
"TINYTEXT",
"VARBINARY",
"VARCHAR",
"YEAR",
"dialect",
"insert",
"Insert",
"match",
)

View File

@@ -0,0 +1,274 @@
# dialects/mysql/aiomysql.py
# Copyright (C) 2005-2026 the SQLAlchemy authors and contributors <see AUTHORS
# file>
#
# This module is part of SQLAlchemy and is released under
# the MIT License: https://www.opensource.org/licenses/mit-license.php
r"""
.. dialect:: mysql+aiomysql
:name: aiomysql
:dbapi: aiomysql
:connectstring: mysql+aiomysql://user:password@host:port/dbname[?key=value&key=value...]
:url: https://github.com/aio-libs/aiomysql
The aiomysql dialect is SQLAlchemy's second Python asyncio dialect.
Using a special asyncio mediation layer, the aiomysql dialect is usable
as the backend for the :ref:`SQLAlchemy asyncio <asyncio_toplevel>`
extension package.
This dialect should normally be used only with the
:func:`_asyncio.create_async_engine` engine creation function::
from sqlalchemy.ext.asyncio import create_async_engine
engine = create_async_engine(
"mysql+aiomysql://user:pass@hostname/dbname?charset=utf8mb4"
)
""" # noqa
from __future__ import annotations
from types import ModuleType
from typing import Any
from typing import Dict
from typing import Optional
from typing import Tuple
from typing import TYPE_CHECKING
from typing import Union
from .pymysql import _connection_ping_reconnects_true
from .pymysql import MySQLDialect_pymysql
from ... import pool
from ... import util
from ...connectors.asyncio import AsyncAdapt_dbapi_connection
from ...connectors.asyncio import AsyncAdapt_dbapi_cursor
from ...connectors.asyncio import AsyncAdapt_dbapi_module
from ...connectors.asyncio import AsyncAdapt_dbapi_ss_cursor
from ...connectors.asyncio import AsyncAdapt_terminate
from ...util import langhelpers
from ...util.concurrency import await_fallback
from ...util.concurrency import await_only
if TYPE_CHECKING:
from ...connectors.asyncio import AsyncIODBAPIConnection
from ...connectors.asyncio import AsyncIODBAPICursor
from ...engine.interfaces import ConnectArgsType
from ...engine.interfaces import DBAPIConnection
from ...engine.interfaces import DBAPICursor
from ...engine.interfaces import DBAPIModule
from ...engine.interfaces import PoolProxiedConnection
from ...engine.url import URL
class AsyncAdapt_aiomysql_cursor(AsyncAdapt_dbapi_cursor):
__slots__ = ()
def _make_new_cursor(
self, connection: AsyncIODBAPIConnection
) -> AsyncIODBAPICursor:
return connection.cursor(self._adapt_connection.dbapi.Cursor)
class AsyncAdapt_aiomysql_ss_cursor(
AsyncAdapt_dbapi_ss_cursor, AsyncAdapt_aiomysql_cursor
):
__slots__ = ()
def _make_new_cursor(
self, connection: AsyncIODBAPIConnection
) -> AsyncIODBAPICursor:
return connection.cursor(
self._adapt_connection.dbapi.aiomysql.cursors.SSCursor
)
class AsyncAdapt_aiomysql_connection(
AsyncAdapt_terminate, AsyncAdapt_dbapi_connection
):
__slots__ = ()
_cursor_cls = AsyncAdapt_aiomysql_cursor
_ss_cursor_cls = AsyncAdapt_aiomysql_ss_cursor
def ping(self, reconnect: bool = False) -> None:
assert not reconnect
if self.dbapi._send_false_to_ping:
self.await_(self._connection.ping(reconnect=False))
else:
self.await_(self._connection.ping())
def character_set_name(self) -> Optional[str]:
return self._connection.character_set_name() # type: ignore[no-any-return] # noqa: E501
def autocommit(self, value: Any) -> None:
self.await_(self._connection.autocommit(value))
def get_autocommit(self) -> bool:
return self._connection.get_autocommit() # type: ignore
def close(self) -> None:
self.await_(self._connection.ensure_closed())
async def _terminate_graceful_close(self) -> None:
await self._connection.ensure_closed()
def _terminate_force_close(self) -> None:
# it's not awaitable.
self._connection.close()
class AsyncAdaptFallback_aiomysql_connection(AsyncAdapt_aiomysql_connection):
__slots__ = ()
await_ = staticmethod(await_fallback)
class AsyncAdapt_aiomysql_dbapi(AsyncAdapt_dbapi_module):
def __init__(self, aiomysql: ModuleType, pymysql: ModuleType):
self.aiomysql = aiomysql
self.pymysql = pymysql
self.paramstyle = "format"
self._init_dbapi_attributes()
self.Cursor, self.SSCursor = self._init_cursors_subclasses()
def _init_dbapi_attributes(self) -> None:
for name in (
"Warning",
"Error",
"InterfaceError",
"DataError",
"DatabaseError",
"OperationalError",
"InterfaceError",
"IntegrityError",
"ProgrammingError",
"InternalError",
"NotSupportedError",
):
setattr(self, name, getattr(self.aiomysql, name))
for name in (
"NUMBER",
"STRING",
"DATETIME",
"BINARY",
"TIMESTAMP",
"Binary",
):
setattr(self, name, getattr(self.pymysql, name))
def connect(self, *arg: Any, **kw: Any) -> AsyncAdapt_aiomysql_connection:
async_fallback = kw.pop("async_fallback", False)
creator_fn = kw.pop("async_creator_fn", self.aiomysql.connect)
if util.asbool(async_fallback):
return AsyncAdaptFallback_aiomysql_connection(
self,
await_fallback(creator_fn(*arg, **kw)),
)
else:
return AsyncAdapt_aiomysql_connection(
self,
await_only(creator_fn(*arg, **kw)),
)
@langhelpers.memoized_property
def _send_false_to_ping(self) -> bool:
"""determine if aiomysql has deprecated, changed the default of,
or removed the 'reconnect' argument of connection.ping().
See #13306 and #10492
""" # noqa: E501
try:
Connection = __import__(
"aiomysql.connection"
).connection.Connection
except (ImportError, AttributeError):
return True
else:
return _connection_ping_reconnects_true(Connection)
def _init_cursors_subclasses(
self,
) -> Tuple[AsyncIODBAPICursor, AsyncIODBAPICursor]:
# suppress unconditional warning emitted by aiomysql
class Cursor(self.aiomysql.Cursor): # type: ignore[misc, name-defined]
async def _show_warnings(
self, conn: AsyncIODBAPIConnection
) -> None:
pass
class SSCursor(self.aiomysql.SSCursor): # type: ignore[misc, name-defined] # noqa: E501
async def _show_warnings(
self, conn: AsyncIODBAPIConnection
) -> None:
pass
return Cursor, SSCursor # type: ignore[return-value]
class MySQLDialect_aiomysql(MySQLDialect_pymysql):
driver = "aiomysql"
supports_statement_cache = True
supports_server_side_cursors = True
_sscursor = AsyncAdapt_aiomysql_ss_cursor
is_async = True
has_terminate = True
@classmethod
def import_dbapi(cls) -> AsyncAdapt_aiomysql_dbapi:
return AsyncAdapt_aiomysql_dbapi(
__import__("aiomysql"), __import__("pymysql")
)
@classmethod
def get_pool_class(cls, url: URL) -> type:
async_fallback = url.query.get("async_fallback", False)
if util.asbool(async_fallback):
return pool.FallbackAsyncAdaptedQueuePool
else:
return pool.AsyncAdaptedQueuePool
def do_terminate(self, dbapi_connection: DBAPIConnection) -> None:
dbapi_connection.terminate()
def create_connect_args(
self, url: URL, _translate_args: Optional[Dict[str, Any]] = None
) -> ConnectArgsType:
return super().create_connect_args(
url, _translate_args=dict(username="user", database="db")
)
def is_disconnect(
self,
e: DBAPIModule.Error,
connection: Optional[Union[PoolProxiedConnection, DBAPIConnection]],
cursor: Optional[DBAPICursor],
) -> bool:
if super().is_disconnect(e, connection, cursor):
return True
else:
str_e = str(e).lower()
return "not connected" in str_e
def _found_rows_client_flag(self) -> int:
from pymysql.constants import CLIENT # type: ignore
return CLIENT.FOUND_ROWS # type: ignore[no-any-return]
def get_driver_connection(
self, connection: DBAPIConnection
) -> AsyncIODBAPIConnection:
return connection._connection # type: ignore[no-any-return]
dialect = MySQLDialect_aiomysql

View File

@@ -0,0 +1,253 @@
# dialects/mysql/asyncmy.py
# Copyright (C) 2005-2026 the SQLAlchemy authors and contributors <see AUTHORS
# file>
#
# This module is part of SQLAlchemy and is released under
# the MIT License: https://www.opensource.org/licenses/mit-license.php
r"""
.. dialect:: mysql+asyncmy
:name: asyncmy
:dbapi: asyncmy
:connectstring: mysql+asyncmy://user:password@host:port/dbname[?key=value&key=value...]
:url: https://github.com/long2ice/asyncmy
Using a special asyncio mediation layer, the asyncmy dialect is usable
as the backend for the :ref:`SQLAlchemy asyncio <asyncio_toplevel>`
extension package.
This dialect should normally be used only with the
:func:`_asyncio.create_async_engine` engine creation function::
from sqlalchemy.ext.asyncio import create_async_engine
engine = create_async_engine(
"mysql+asyncmy://user:pass@hostname/dbname?charset=utf8mb4"
)
""" # noqa
from __future__ import annotations
from types import ModuleType
from typing import Any
from typing import NoReturn
from typing import Optional
from typing import TYPE_CHECKING
from typing import Union
from .pymysql import _connection_ping_reconnects_true
from .pymysql import MySQLDialect_pymysql
from ... import pool
from ... import util
from ...connectors.asyncio import AsyncAdapt_dbapi_connection
from ...connectors.asyncio import AsyncAdapt_dbapi_cursor
from ...connectors.asyncio import AsyncAdapt_dbapi_module
from ...connectors.asyncio import AsyncAdapt_dbapi_ss_cursor
from ...connectors.asyncio import AsyncAdapt_terminate
from ...util import langhelpers
from ...util.concurrency import await_fallback
from ...util.concurrency import await_only
if TYPE_CHECKING:
from ...connectors.asyncio import AsyncIODBAPIConnection
from ...connectors.asyncio import AsyncIODBAPICursor
from ...engine.interfaces import ConnectArgsType
from ...engine.interfaces import DBAPIConnection
from ...engine.interfaces import DBAPICursor
from ...engine.interfaces import DBAPIModule
from ...engine.interfaces import PoolProxiedConnection
from ...engine.url import URL
class AsyncAdapt_asyncmy_cursor(AsyncAdapt_dbapi_cursor):
__slots__ = ()
class AsyncAdapt_asyncmy_ss_cursor(
AsyncAdapt_dbapi_ss_cursor, AsyncAdapt_asyncmy_cursor
):
__slots__ = ()
def _make_new_cursor(
self, connection: AsyncIODBAPIConnection
) -> AsyncIODBAPICursor:
return connection.cursor(
self._adapt_connection.dbapi.asyncmy.cursors.SSCursor
)
class AsyncAdapt_asyncmy_connection(
AsyncAdapt_terminate, AsyncAdapt_dbapi_connection
):
__slots__ = ()
_cursor_cls = AsyncAdapt_asyncmy_cursor
_ss_cursor_cls = AsyncAdapt_asyncmy_ss_cursor
def _handle_exception(self, error: Exception) -> NoReturn:
if isinstance(error, AttributeError):
raise self.dbapi.InternalError(
"network operation failed due to asyncmy attribute error"
) from error
raise error
def ping(self, reconnect: bool = False) -> None:
assert not reconnect
return self.await_(self._do_ping())
async def _do_ping(self) -> None:
try:
async with self._execute_mutex:
if self.dbapi._send_false_to_ping:
await self._connection.ping(reconnect=False)
else:
await self._connection.ping()
except Exception as error:
self._handle_exception(error)
def character_set_name(self) -> Optional[str]:
return self._connection.character_set_name() # type: ignore[no-any-return] # noqa: E501
def autocommit(self, value: Any) -> None:
self.await_(self._connection.autocommit(value))
def get_autocommit(self) -> bool:
return self._connection.get_autocommit() # type: ignore
def close(self) -> None:
self.await_(self._connection.ensure_closed())
async def _terminate_graceful_close(self) -> None:
await self._connection.ensure_closed()
def _terminate_force_close(self) -> None:
# it's not awaitable.
self._connection.close()
class AsyncAdaptFallback_asyncmy_connection(AsyncAdapt_asyncmy_connection):
__slots__ = ()
await_ = staticmethod(await_fallback)
class AsyncAdapt_asyncmy_dbapi(AsyncAdapt_dbapi_module):
def __init__(self, asyncmy: ModuleType):
self.asyncmy = asyncmy
self.paramstyle = "format"
self._init_dbapi_attributes()
def _init_dbapi_attributes(self) -> None:
for name in (
"Warning",
"Error",
"InterfaceError",
"DataError",
"DatabaseError",
"OperationalError",
"InterfaceError",
"IntegrityError",
"ProgrammingError",
"InternalError",
"NotSupportedError",
):
setattr(self, name, getattr(self.asyncmy.errors, name))
STRING = util.symbol("STRING")
NUMBER = util.symbol("NUMBER")
BINARY = util.symbol("BINARY")
DATETIME = util.symbol("DATETIME")
TIMESTAMP = util.symbol("TIMESTAMP")
Binary = staticmethod(bytes)
def connect(self, *arg: Any, **kw: Any) -> AsyncAdapt_asyncmy_connection:
async_fallback = kw.pop("async_fallback", False)
creator_fn = kw.pop("async_creator_fn", self.asyncmy.connect)
if util.asbool(async_fallback):
return AsyncAdaptFallback_asyncmy_connection(
self,
await_fallback(creator_fn(*arg, **kw)),
)
else:
return AsyncAdapt_asyncmy_connection(
self,
await_only(creator_fn(*arg, **kw)),
)
@langhelpers.memoized_property
def _send_false_to_ping(self) -> bool:
"""determine if asyncmy has deprecated, changed the default of,
or removed the 'reconnect' argument of connection.ping().
See #13306 and #10492
""" # noqa: E501
try:
Connection = __import__("asyncmy.connection").connection.Connection
except (ImportError, AttributeError):
return True
else:
return _connection_ping_reconnects_true(Connection)
class MySQLDialect_asyncmy(MySQLDialect_pymysql):
driver = "asyncmy"
supports_statement_cache = True
supports_server_side_cursors = True
_sscursor = AsyncAdapt_asyncmy_ss_cursor
is_async = True
has_terminate = True
@classmethod
def import_dbapi(cls) -> DBAPIModule:
return AsyncAdapt_asyncmy_dbapi(__import__("asyncmy"))
@classmethod
def get_pool_class(cls, url: URL) -> type:
async_fallback = url.query.get("async_fallback", False)
if util.asbool(async_fallback):
return pool.FallbackAsyncAdaptedQueuePool
else:
return pool.AsyncAdaptedQueuePool
def do_terminate(self, dbapi_connection: DBAPIConnection) -> None:
dbapi_connection.terminate()
def create_connect_args(self, url: URL) -> ConnectArgsType: # type: ignore[override] # noqa: E501
return super().create_connect_args(
url, _translate_args=dict(username="user", database="db")
)
def is_disconnect(
self,
e: DBAPIModule.Error,
connection: Optional[Union[PoolProxiedConnection, DBAPIConnection]],
cursor: Optional[DBAPICursor],
) -> bool:
if super().is_disconnect(e, connection, cursor):
return True
else:
str_e = str(e).lower()
return (
"not connected" in str_e or "network operation failed" in str_e
)
def _found_rows_client_flag(self) -> int:
from asyncmy.constants import CLIENT # type: ignore
return CLIENT.FOUND_ROWS # type: ignore[no-any-return]
def get_driver_connection(
self, connection: DBAPIConnection
) -> AsyncIODBAPIConnection:
return connection._connection # type: ignore[no-any-return]
dialect = MySQLDialect_asyncmy

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,107 @@
# dialects/mysql/cymysql.py
# Copyright (C) 2005-2026 the SQLAlchemy authors and contributors
# <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
# the MIT License: https://www.opensource.org/licenses/mit-license.php
r"""
.. dialect:: mysql+cymysql
:name: CyMySQL
:dbapi: cymysql
:connectstring: mysql+cymysql://<username>:<password>@<host>/<dbname>[?<options>]
:url: https://github.com/nakagami/CyMySQL
.. note::
The CyMySQL dialect is **not tested as part of SQLAlchemy's continuous
integration** and may have unresolved issues. The recommended MySQL
dialects are mysqlclient and PyMySQL.
""" # noqa
from __future__ import annotations
from typing import Any
from typing import Iterable
from typing import Optional
from typing import TYPE_CHECKING
from typing import Union
from .base import MySQLDialect
from .mysqldb import MySQLDialect_mysqldb
from .types import BIT
from ... import util
if TYPE_CHECKING:
from ...engine.base import Connection
from ...engine.interfaces import DBAPIConnection
from ...engine.interfaces import DBAPICursor
from ...engine.interfaces import DBAPIModule
from ...engine.interfaces import Dialect
from ...engine.interfaces import PoolProxiedConnection
from ...sql.type_api import _ResultProcessorType
class _cymysqlBIT(BIT):
def result_processor(
self, dialect: Dialect, coltype: object
) -> Optional[_ResultProcessorType[Any]]:
"""Convert MySQL's 64 bit, variable length binary string to a long."""
def process(value: Optional[Iterable[int]]) -> Optional[int]:
if value is not None:
v = 0
for i in iter(value):
v = v << 8 | i
return v
return value
return process
class MySQLDialect_cymysql(MySQLDialect_mysqldb):
driver = "cymysql"
supports_statement_cache = True
description_encoding = None
supports_sane_rowcount = True
supports_sane_multi_rowcount = False
supports_unicode_statements = True
colspecs = util.update_copy(MySQLDialect.colspecs, {BIT: _cymysqlBIT})
@classmethod
def import_dbapi(cls) -> DBAPIModule:
return __import__("cymysql")
def _detect_charset(self, connection: Connection) -> str:
return connection.connection.charset # type: ignore[no-any-return]
def _extract_error_code(self, exception: DBAPIModule.Error) -> int:
return exception.errno # type: ignore[no-any-return]
def is_disconnect(
self,
e: DBAPIModule.Error,
connection: Optional[Union[PoolProxiedConnection, DBAPIConnection]],
cursor: Optional[DBAPICursor],
) -> bool:
if isinstance(e, self.loaded_dbapi.OperationalError):
return self._extract_error_code(e) in (
2006,
2013,
2014,
2045,
2055,
)
elif isinstance(e, self.loaded_dbapi.InterfaceError):
# if underlying connection is closed,
# this is the error you get
return True
else:
return False
dialect = MySQLDialect_cymysql