MySQL 和 MariaDB

对 MySQL / MariaDB 数据库的支持。

下表总结了当前对数据库发布版本的支持级别。

支持的 MySQL / MariaDB 版本

支持类型

版本

受支持版本

5.6+ / 10+

尽力支持

5.0.2+ / 5.0.2+

DBAPI 支持

以下是可用的方言/DBAPI 选项。请参考各个 DBAPI 部分以获取连接信息。

支持的版本和特性

SQLAlchemy 支持从 5.0.2 版本到最新版本的 MySQL,以及所有最新版本的 MariaDB。有关任何给定服务器版本中支持的功能的详细信息,请参阅官方 MySQL 文档。

在版本 1.4 中更改: 现在支持的最低 MySQL 版本为 5.0.2。

MariaDB 支持

MariaDB 版本的 MySQL 保留了与 MySQL 协议的基本兼容性,但这两种产品的开发仍在继续分歧。在 SQLAlchemy 领域内,这两个数据库在语法和行为上存在少量差异,SQLAlchemy 会自动适应这些差异。要连接到 MariaDB 数据库,无需更改数据库 URL

engine = create_engine(
    "mysql+pymysql://user:pass@some_mariadb/dbname?charset=utf8mb4"
)

首次连接时,SQLAlchemy 方言会采用服务器版本检测方案,以确定后端的数据库是否报告为 MariaDB。根据此标志,方言可以在其行为必须不同的领域做出不同的选择。

仅 MariaDB 模式

该方言还支持可选的“仅 MariaDB”连接模式,这对于应用程序使用 MariaDB 特有功能且与 MySQL 数据库不兼容的情况可能很有用。要使用此操作模式,请将上述 URL 中的 “mysql” 令牌替换为 “mariadb”

engine = create_engine(
    "mariadb+pymysql://user:pass@some_mariadb/dbname?charset=utf8mb4"
)

上面的引擎在首次连接时,如果服务器版本检测检测到后端数据库不是 MariaDB,则会引发错误。

当使用方言名称为 "mariadb" 的引擎时,所有在名称中包含 “mysql” 的 mysql 特有选项现在都命名为 “mariadb”。这意味着像 mysql_engine 这样的选项应命名为 mariadb_engine 等。“mysql” 和 “mariadb” 选项可以同时用于在 URL 中同时使用 “mysql” 和 “mariadb” 方言的应用程序

my_table = Table(
    "mytable",
    metadata,
    Column("id", Integer, primary_key=True),
    Column("textdata", String(50)),
    mariadb_engine="InnoDB",
    mysql_engine="InnoDB",
)

Index(
    "textdata_ix",
    my_table.c.textdata,
    mysql_prefix="FULLTEXT",
    mariadb_prefix="FULLTEXT",
)

当反射上述结构时,也会发生类似的行为,即当数据库 URL 基于 “mariadb” 名称时,“mariadb” 前缀将出现在选项名称中。

在版本 1.4 中新增: 为 MySQL 方言添加了支持 “仅 MariaDB 模式” 的 “mariadb” 方言名称。

连接超时和断开

MySQL / MariaDB 具有自动连接关闭行为,对于空闲固定时间段的连接(默认为八小时)。为了避免此问题,请使用 create_engine.pool_recycle 选项,该选项确保连接如果在池中存在固定秒数,则会被丢弃并替换为新连接

engine = create_engine("mysql+mysqldb://...", pool_recycle=3600)

为了更全面地检测池连接的断开,包括适应服务器重启和网络问题,可以使用预 ping 方法。请参阅 处理断开连接 以了解当前方法。

另请参阅

处理断开连接 - 关于处理超时连接以及数据库重启的几种技术的背景信息。

CREATE TABLE 参数,包括存储引擎

MySQL 和 MariaDB 的 CREATE TABLE 语法都包含各种特殊选项,包括 ENGINECHARSETMAX_ROWSROW_FORMATINSERT_METHOD 以及更多。为了适应这些参数的渲染,请指定 mysql_argument_name="value" 形式。例如,要指定 ENGINEInnoDBCHARSETutf8mb4KEY_BLOCK_SIZE1024 的表

Table(
    "mytable",
    metadata,
    Column("data", String(32)),
    mysql_engine="InnoDB",
    mysql_charset="utf8mb4",
    mysql_key_block_size="1024",
)

当支持 仅 MariaDB 模式 模式时,也必须包括针对 “mariadb” 前缀的类似键。这些值当然可以独立变化,以便可以维护 MySQL 与 MariaDB 上的不同设置

# support both "mysql" and "mariadb-only" engine URLs

Table(
    "mytable",
    metadata,
    Column("data", String(32)),
    mysql_engine="InnoDB",
    mariadb_engine="InnoDB",
    mysql_charset="utf8mb4",
    mariadb_charset="utf8",
    mysql_key_block_size="1024",
    mariadb_key_block_size="1024",
)

MySQL / MariaDB 方言通常会将指定为 mysql_keyword_name 的任何关键字转换为在 CREATE TABLE 语句中渲染为 KEYWORD_NAME。其中一些名称将渲染为带空格而不是下划线;为了支持这一点,MySQL 方言了解这些特定名称,包括 DATA DIRECTORY (例如 mysql_data_directory)、CHARACTER SET (例如 mysql_character_set) 和 INDEX DIRECTORY (例如 mysql_index_directory)。

最常见的参数是 mysql_engine,它指的是表的存储引擎。从历史上看,MySQL 服务器安装通常默认为 MyISAM,尽管较新版本可能默认为 InnoDBInnoDB 引擎通常因其对事务和外键的支持而受到青睐。

在存储引擎为 MyISAM 的 MySQL / MariaDB 数据库中创建的 Table 本质上是非事务性的,这意味着任何引用此表的 INSERT/UPDATE/DELETE 语句都将作为自动提交调用。它也不支持外键约束;虽然 CREATE TABLE 语句接受外键选项,但当使用 MyISAM 存储引擎时,这些参数将被丢弃。反射这样的表也不会产生外键约束信息。

为了实现完全原子事务以及对外键约束的支持,所有参与的 CREATE TABLE 语句都必须指定事务引擎,在绝大多数情况下,事务引擎都是 InnoDB

可以使用类似的选项类似地指定分区。在下面的示例中,create table 将指定 PARTITION_BYPARTITIONSSUBPARTITIONSSUBPARTITION_BY

# can also use mariadb_* prefix
Table(
    "testtable",
    MetaData(),
    Column("id", Integer(), primary_key=True, autoincrement=True),
    Column("other_id", Integer(), primary_key=True, autoincrement=False),
    mysql_partitions="2",
    mysql_partition_by="KEY(other_id)",
    mysql_subpartition_by="HASH(some_expr)",
    mysql_subpartitions="2",
)

这将渲染为

CREATE TABLE testtable (
        id INTEGER NOT NULL AUTO_INCREMENT,
        other_id INTEGER NOT NULL,
        PRIMARY KEY (id, other_id)
)PARTITION BY KEY(other_id) PARTITIONS 2 SUBPARTITION BY HASH(some_expr) SUBPARTITIONS 2

大小写敏感性和表反射

MySQL 和 MariaDB 对大小写敏感的标识符名称的支持不一致,支持取决于底层操作系统的具体细节。但是,已经观察到,无论存在什么大小写敏感性行为,外键声明中的表名总是从数据库中接收为全小写,这使得准确反射使用混合大小写标识符名称的相互关联的模式成为不可能。

因此,强烈建议在 SQLAlchemy 以及 MySQL / MariaDB 数据库本身中将表名声明为全小写,尤其是在要使用数据库反射功能的情况下。

事务隔离级别

所有 MySQL / MariaDB 方言都支持通过方言特定的参数 create_engine.isolation_level(由 create_engine() 接受)以及传递给 Connection.execution_options()Connection.execution_options.isolation_level 参数来设置事务隔离级别。此功能通过为每个新连接发出命令 SET SESSION TRANSACTION ISOLATION LEVEL <level> 来工作。对于特殊的 AUTOCOMMIT 隔离级别,使用 DBAPI 特定的技术。

要使用 create_engine() 设置隔离级别

engine = create_engine(
    "mysql+mysqldb://scott:tiger@localhost/test",
    isolation_level="READ UNCOMMITTED",
)

要使用每个连接的执行选项进行设置

connection = engine.connect()
connection = connection.execution_options(isolation_level="READ COMMITTED")

isolation_level 的有效值包括

  • READ COMMITTED

  • READ UNCOMMITTED

  • REPEATABLE READ

  • SERIALIZABLE

  • AUTOCOMMIT

特殊的 AUTOCOMMIT 值使用特定 DBAPI 提供的各种 “autocommit” 属性,目前受 MySQLdb、MySQL-Client、MySQL-Connector Python 和 PyMySQL 支持。使用它,数据库连接将为 SELECT @@autocommit; 的值返回 true。

还有更多用于隔离级别配置的选项,例如链接到主 Engine 的 “子引擎” 对象,每个对象应用不同的隔离级别设置。有关背景信息,请参阅 设置事务隔离级别,包括 DBAPI 自动提交 中的讨论。

AUTO_INCREMENT 行为

创建表时,SQLAlchemy 将自动在第一个未标记为外键的 Integer 主键列上设置 AUTO_INCREMENT

>>> t = Table(
...     "mytable", metadata, Column("mytable_id", Integer, primary_key=True)
... )
>>> t.create()
CREATE TABLE mytable (
        id INTEGER NOT NULL AUTO_INCREMENT,
        PRIMARY KEY (id)
)

您可以通过将 False 传递给 Column.autoincrement 参数(Column 的参数)来禁用此行为。此标志还可以用于在某些存储引擎的多列键中的辅助列上启用自动递增

Table(
    "mytable",
    metadata,
    Column("gid", Integer, primary_key=True, autoincrement=False),
    Column("id", Integer, primary_key=True),
)

服务器端游标

mysqlclient、PyMySQL、mariadbconnector 方言支持服务器端游标,其他方言也可能支持。这使用了 “buffered=True/False” 标志(如果可用),或者使用诸如 MySQLdb.cursors.SSCursorpymysql.cursors.SSCursor 之类的类在内部实现。

通过使用 Connection.execution_options.stream_results 连接执行选项,在每个语句的基础上启用服务器端游标

with engine.connect() as conn:
    result = conn.execution_options(stream_results=True).execute(
        text("select * from table")
    )

请注意,某些类型的 SQL 语句可能不支持服务器端游标;通常,只有返回行的 SQL 语句才应与此选项一起使用。

自版本 1.4 起已弃用: 方言级别的 server_side_cursors 标志已弃用,将在未来的版本中删除。请使用 Connection.stream_results 执行选项以获得非缓冲游标支持。

Unicode

字符集选择

大多数 MySQL / MariaDB DBAPI 都提供设置连接的客户端字符集的选项。这通常通过 URL 中的 charset 参数传递,例如

e = create_engine(
    "mysql+pymysql://scott:tiger@localhost/test?charset=utf8mb4"
)

此字符集是连接的客户端字符集。某些 MySQL DBAPI 会将此值默认为诸如 latin1 之类的值,而另一些则会使用 my.cnf 文件中的 default-character-set 设置。应查阅正在使用的 DBAPI 的文档以了解具体行为。

用于 Unicode 的编码传统上一直是 'utf8'。但是,对于 MySQL 5.5.3 版本和 MariaDB 5.5 及更高版本,引入了一种新的 MySQL 特有编码 'utf8mb4',并且从 MySQL 8.0 开始,如果在任何服务器端指令中指定了普通的 utf8,服务器都会发出警告,并替换为 utf8mb3。这种新编码的基本原理是,MySQL 的旧版 utf-8 编码仅支持最多三个字节的代码点,而不是四个字节。因此,当与包含大小超过三个字节的代码点的 MySQL 或 MariaDB 数据库通信时,如果数据库和客户端 DBAPI 都支持,则首选这种新的字符集,如

e = create_engine(
    "mysql+pymysql://scott:tiger@localhost/test?charset=utf8mb4"
)

所有现代 DBAPI 都应支持 utf8mb4 字符集。

为了对使用旧版 utf8 创建的模式使用 utf8mb4 编码,可能需要更改 MySQL/MariaDB 模式和/或服务器配置。

另请参阅

utf8mb4 字符集 - 在 MySQL 文档中

处理二进制数据警告和 Unicode

MySQL 5.6、5.7 及更高版本(在撰写本文时 MariaDB 不是)现在在尝试将二进制数据传递到数据库时发出警告,而当字符集编码也到位时,如果二进制数据本身对于该编码无效

default.py:509: Warning: (1300, "Invalid utf8mb4 character string:
'F9876A'")
  cursor.execute(statement, parameters)

此警告是由于 MySQL 客户端库尝试将二进制字符串解释为 unicode 对象,即使使用了诸如 LargeBinary 之类的数据类型。为了解决这个问题,SQL 语句需要在任何呈现为如下形式的非 NULL 值之前存在二进制 “字符集引入器”

INSERT INTO table (data) VALUES (_binary %s)

这些字符集引入器由 DBAPI 驱动程序提供,前提是使用 mysqlclient 或 PyMySQL(两者都是推荐的)。将查询字符串参数 binary_prefix=true 添加到 URL 以修复此警告

# mysqlclient
engine = create_engine(
    "mysql+mysqldb://scott:tiger@localhost/test?charset=utf8mb4&binary_prefix=true"
)

# PyMySQL
engine = create_engine(
    "mysql+pymysql://scott:tiger@localhost/test?charset=utf8mb4&binary_prefix=true"
)

binary_prefix 标志可能受其他 MySQL 驱动程序支持,也可能不受支持。

SQLAlchemy 本身无法可靠地渲染此 _binary 前缀,因为它不适用于 NULL 值,NULL 值可以作为绑定参数发送。由于 MySQL 驱动程序将参数直接渲染到 SQL 字符串中,因此它是传递此附加关键字的最有效位置。

另请参阅

字符集引入器 - 在 MySQL 网站上

ANSI 引用风格

MySQL / MariaDB 具有两种标识符 “引用风格”,一种使用反引号,另一种使用引号,例如 `some_identifier`"some_identifier"。所有 MySQL 方言都通过检查与特定 Engine 首次建立连接时 sql_mode 的值来检测正在使用的版本。当渲染表和列名以及反射现有数据库结构时,此引用风格会发挥作用。检测完全是自动的,使用任何一种引用风格都不需要特殊配置。

更改 sql_mode

MySQL 支持在 服务器 SQL 模式 中为服务器和客户端运行。要更改给定应用程序的 sql_mode,开发人员可以利用 SQLAlchemy 的事件系统。

在以下示例中,事件系统用于在 first_connectconnect 事件上设置 sql_mode

from sqlalchemy import create_engine, event

eng = create_engine(
    "mysql+mysqldb://scott:tiger@localhost/test", echo="debug"
)


# `insert=True` will ensure this is the very first listener to run
@event.listens_for(eng, "connect", insert=True)
def connect(dbapi_connection, connection_record):
    cursor = dbapi_connection.cursor()
    cursor.execute("SET sql_mode = 'STRICT_ALL_TABLES'")


conn = eng.connect()

在上面所示的示例中,“connect” 事件将在为给定池首次创建特定 DBAPI 连接时,在连接可用于连接池之前,在连接上调用 “SET” 语句。此外,由于该函数已使用 insert=True 注册,因此它将被添加到已注册函数的内部列表的前面。

MySQL / MariaDB SQL 扩展

许多 MySQL / MariaDB SQL 扩展通过 SQLAlchemy 的通用函数和运算符支持来处理

table.select(table.c.password == func.md5("plaintext"))
table.select(table.c.username.op("regexp")("^[a-d]"))

当然,任何有效的 SQL 语句也可以作为字符串执行。

目前提供对 MySQL / MariaDB SQL 扩展的一些有限的直接支持。

  • INSERT..ON DUPLICATE KEY UPDATE:请参阅 INSERT…ON DUPLICATE KEY UPDATE (Upsert)

  • SELECT pragma,使用 Select.prefix_with()Query.prefix_with()

    select(...).prefix_with(["HIGH_PRIORITY", "SQL_SMALL_RESULT"])
  • 带有 LIMIT 的 UPDATE

    update(...).with_dialect_options(mysql_limit=10, mariadb_limit=10)
  • 带有 LIMIT 的 DELETE

    delete(...).with_dialect_options(mysql_limit=10, mariadb_limit=10)

    在版本 2.0.37 中新增: 添加了带 limit 的 delete

  • 优化器提示,使用 Select.prefix_with()Query.prefix_with()

    select(...).prefix_with("/*+ NO_RANGE_OPTIMIZATION(t4 PRIMARY) */")
  • 索引提示,使用 Select.with_hint()Query.with_hint()

    select(...).with_hint(some_table, "USE INDEX xyz")
  • MATCH 运算符支持

    from sqlalchemy.dialects.mysql import match
    
    select(...).where(match(col1, col2, against="some expr").in_boolean_mode())

    另请参阅

    match

INSERT/DELETE…RETURNING

MariaDB 方言支持 10.5+ 的 INSERT..RETURNINGDELETE..RETURNING (10.0+) 语法。INSERT..RETURNING 可以在某些情况下自动使用,以便获取新生成的标识符,以取代使用 cursor.lastrowid 的传统方法,但是,对于简单的单语句情况,cursor.lastrowid 目前仍然是首选,因为它具有更好的性能。

要指定显式的 RETURNING 子句,请在每个语句的基础上使用 _UpdateBase.returning() 方法

# INSERT..RETURNING
result = connection.execute(
    table.insert().values(name="foo").returning(table.c.col1, table.c.col2)
)
print(result.all())

# DELETE..RETURNING
result = connection.execute(
    table.delete()
    .where(table.c.name == "foo")
    .returning(table.c.col1, table.c.col2)
)
print(result.all())

在版本 2.0 中新增: 添加了对 MariaDB RETURNING 的支持

INSERT…ON DUPLICATE KEY UPDATE (Upsert)

MySQL / MariaDB 允许通过 INSERT 语句的 ON DUPLICATE KEY UPDATE 子句将行 “upsert”(更新或插入)到表中。只有当候选行与表中现有的主键或唯一键不匹配时,才会插入该行;否则,将执行 UPDATE。该语句允许单独指定要 INSERT 的值与要 UPDATE 的值。

SQLAlchemy 通过 MySQL 特定的 insert() 函数提供 ON DUPLICATE KEY UPDATE 支持,该函数提供生成方法 Insert.on_duplicate_key_update()

>>> from sqlalchemy.dialects.mysql import insert

>>> insert_stmt = insert(my_table).values(
...     id="some_existing_id", data="inserted value"
... )

>>> on_duplicate_key_stmt = insert_stmt.on_duplicate_key_update(
...     data=insert_stmt.inserted.data, status="U"
... )
>>> print(on_duplicate_key_stmt)
INSERT INTO my_table (id, data) VALUES (%s, %s) ON DUPLICATE KEY UPDATE data = VALUES(data), status = %s

与 PostgreSQL 的 “ON CONFLICT” 短语不同,“ON DUPLICATE KEY UPDATE” 短语将始终匹配任何主键或唯一键,并且如果存在匹配项,将始终执行 UPDATE 操作;它没有引发错误或跳过执行 UPDATE 操作的选项。

ON DUPLICATE KEY UPDATE 用于对已存在的行执行更新,可以使用新值和来自建议插入的值的任意组合。这些值通常使用传递给 Insert.on_duplicate_key_update() 的关键字参数指定,给定列键值(通常是列的名称,除非它指定了 Column.key)作为键,字面值或 SQL 表达式作为值。

>>> insert_stmt = insert(my_table).values(
...     id="some_existing_id", data="inserted value"
... )

>>> on_duplicate_key_stmt = insert_stmt.on_duplicate_key_update(
...     data="some data",
...     updated_at=func.current_timestamp(),
... )

>>> print(on_duplicate_key_stmt)
INSERT INTO my_table (id, data) VALUES (%s, %s) ON DUPLICATE KEY UPDATE data = %s, updated_at = CURRENT_TIMESTAMP

UpdateBase.values() 的方式类似,也接受其他参数形式,包括单个字典。

>>> on_duplicate_key_stmt = insert_stmt.on_duplicate_key_update(
...     {"data": "some data", "updated_at": func.current_timestamp()},
... )

以及 2 元组的列表,这将自动提供参数排序的 UPDATE 语句,方式类似于 参数排序更新 中描述的方式。与 Update 对象不同,由于此上下文中的参数形式是明确的,因此不需要特殊的标志来指定意图。

>>> on_duplicate_key_stmt = insert_stmt.on_duplicate_key_update(
...     [
...         ("data", "some data"),
...         ("updated_at", func.current_timestamp()),
...     ]
... )

>>> print(on_duplicate_key_stmt)
INSERT INTO my_table (id, data) VALUES (%s, %s) ON DUPLICATE KEY UPDATE data = %s, updated_at = CURRENT_TIMESTAMP

在版本 1.3 中更改: 支持 MySQL ON DUPLICATE KEY UPDATE 中的参数排序 UPDATE 子句

警告

Insert.on_duplicate_key_update() 方法**不**考虑 Python 端的默认 UPDATE 值或生成函数,例如,使用 Column.onupdate 指定的那些。这些值不会为 ON DUPLICATE KEY 类型的 UPDATE 执行,除非它们在参数中手动显式指定。

为了引用建议的插入行,特殊别名 Insert.inserted 可作为 Insert 对象上的属性使用;此对象是一个 ColumnCollection,其中包含目标表的所有列。

>>> stmt = insert(my_table).values(
...     id="some_id", data="inserted value", author="jlh"
... )

>>> do_update_stmt = stmt.on_duplicate_key_update(
...     data="updated value", author=stmt.inserted.author
... )

>>> print(do_update_stmt)
INSERT INTO my_table (id, data, author) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE data = %s, author = VALUES(author)

渲染后,“inserted” 命名空间将生成表达式 VALUES(<columnname>)

在版本 1.2 中新增: 添加了对 MySQL ON DUPLICATE KEY UPDATE 子句的支持

rowcount 支持

SQLAlchemy 将 DBAPI cursor.rowcount 属性标准化为 “UPDATE 或 DELETE 语句匹配的行数” 的常用定义。这与大多数 MySQL DBAPI 驱动程序的默认设置相矛盾,后者的默认设置是 “实际修改/删除的行数”。 因此,SQLAlchemy MySQL 方言始终在连接时添加 constants.CLIENT.FOUND_ROWS 标志,或目标方言的等效标志。此设置当前是硬编码的。

另请参阅

CursorResult.rowcount

MySQL / MariaDB 特定的索引选项

SQLAlchemy 提供了 MySQL 和 MariaDB 特有的对 Index 构造的扩展。

索引长度

MySQL 和 MariaDB 都提供了一个选项来创建具有特定长度的索引条目,“长度” 是指每个值中将成为索引一部分的字符数或字节数。SQLAlchemy 通过 mysql_length 和/或 mariadb_length 参数提供此功能。

Index("my_index", my_table.c.data, mysql_length=10, mariadb_length=10)

Index("a_b_idx", my_table.c.a, my_table.c.b, mysql_length={"a": 4, "b": 9})

Index(
    "a_b_idx", my_table.c.a, my_table.c.b, mariadb_length={"a": 4, "b": 9}
)

前缀长度对于非二进制字符串类型以字符为单位,对于二进制字符串类型以字节为单位。传递给关键字参数的值必须是整数(因此,为索引的所有列指定相同的前缀长度值)或字典,其中键是列名,值是相应列的前缀长度值。MySQL 和 MariaDB 仅允许 CHAR、VARCHAR、TEXT、BINARY、VARBINARY 和 BLOB 类型的索引列设置长度。

索引前缀

MySQL 存储引擎允许您在创建索引时指定索引前缀。SQLAlchemy 通过 Index 上的 mysql_prefix 参数提供此功能。

Index("my_index", my_table.c.data, mysql_prefix="FULLTEXT")

传递给关键字参数的值将简单地传递到基础的 CREATE INDEX 语句,因此它必须是您的 MySQL 存储引擎的有效索引前缀。

另请参阅

CREATE INDEX - MySQL 文档

索引类型

某些 MySQL 存储引擎允许您在创建索引或主键约束时指定索引类型。SQLAlchemy 通过 Index 上的 mysql_using 参数提供此功能。

Index(
    "my_index", my_table.c.data, mysql_using="hash", mariadb_using="hash"
)

以及 PrimaryKeyConstraint 上的 mysql_using 参数。

PrimaryKeyConstraint("data", mysql_using="hash", mariadb_using="hash")

传递给关键字参数的值将简单地传递到基础的 CREATE INDEX 或 PRIMARY KEY 子句,因此它必须是您的 MySQL 存储引擎的有效索引类型。

更多信息请参考:

https://dev.mysqlserver.cn/doc/refman/5.0/en/create-index.html

https://dev.mysqlserver.cn/doc/refman/5.0/en/create-table.html

索引解析器

MySQL 中的 CREATE FULLTEXT INDEX 也支持 “WITH PARSER” 选项。这可以通过关键字参数 mysql_with_parser 来使用。

Index(
    "my_index",
    my_table.c.data,
    mysql_prefix="FULLTEXT",
    mysql_with_parser="ngram",
    mariadb_prefix="FULLTEXT",
    mariadb_with_parser="ngram",
)

版本 1.3 新增。

MySQL / MariaDB 外键

MySQL 和 MariaDB 关于外键的行为有一些重要的注意事项。

应避免使用的外键参数

MySQL 和 MariaDB 都不支持外键参数 “DEFERRABLE”、“INITIALLY” 或 “MATCH”。将 deferrableinitially 关键字参数与 ForeignKeyConstraintForeignKey 一起使用,将会导致这些关键字在 DDL 表达式中呈现,然后在 MySQL 或 MariaDB 上引发错误。为了在 MySQL / MariaDB 后端忽略这些关键字的情况下在外键上使用它们,请使用自定义编译规则。

from sqlalchemy.ext.compiler import compiles
from sqlalchemy.schema import ForeignKeyConstraint


@compiles(ForeignKeyConstraint, "mysql", "mariadb")
def process(element, compiler, **kw):
    element.deferrable = element.initially = None
    return compiler.visit_foreign_key_constraint(element, **kw)

“MATCH” 关键字实际上更具隐蔽性,并且 SQLAlchemy 明确禁止将其与 MySQL 或 MariaDB 后端结合使用。MySQL / MariaDB 会静默忽略此参数,但此外,还会导致后端忽略 ON UPDATE 和 ON DELETE 选项。因此,MATCH 永远不应与 MySQL / MariaDB 后端一起使用;与 DEFERRABLE 和 INITIALLY 的情况一样,可以使用自定义编译规则在 DDL 定义时更正 ForeignKeyConstraint。

外键约束的反射

并非所有 MySQL / MariaDB 存储引擎都支持外键。当使用非常常见的 MyISAM MySQL 存储引擎时,表反射加载的信息将不包括外键。对于这些表,您可以在反射时提供一个 ForeignKeyConstraint

Table(
    "mytable",
    metadata,
    ForeignKeyConstraint(["other_id"], ["othertable.other_id"]),
    autoload_with=engine,
)

MySQL / MariaDB 唯一约束和反射

SQLAlchemy 同时支持带有 unique=True 标志的 Index 构造(表示 UNIQUE 索引),以及表示 UNIQUE 约束的 UniqueConstraint 构造。当发出 DDL 以创建这些约束时,MySQL / MariaDB 都支持这两种对象/语法。但是,MySQL / MariaDB 没有与唯一索引分开的唯一约束构造;也就是说,MySQL / MariaDB 上的 “UNIQUE” 约束等同于创建 “UNIQUE INDEX”。

在反射这些构造时,Inspector.get_indexes()Inspector.get_unique_constraints() 方法都将为 MySQL / MariaDB 中的 UNIQUE 索引返回一个条目。但是,当使用 Table(..., autoload_with=engine) 执行完整表反射时,UniqueConstraint 构造**不**是完全反射的 Table 构造的一部分(在任何情况下都是如此);此构造始终由 Index 表示,并且 unique=True 设置存在于 Table.indexes 集合中。

TIMESTAMP / DATETIME 问题

为 MySQL / MariaDB 的 explicit_defaults_for_timestamp 渲染 ON UPDATE CURRENT TIMESTAMP

MySQL / MariaDB 历史上将 TIMESTAMP 数据类型的 DDL 扩展为短语 “TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP”,其中包括非标准的 SQL,当发生 UPDATE 时,它会自动使用当前时间戳更新列,从而消除了在需要服务器端更新更改的情况下通常使用触发器的需要。

MySQL 5.6 引入了一个新的标志 explicit_defaults_for_timestamp,它禁用了上述行为,而在 MySQL 8 中,此标志默认为 true,这意味着为了在不更改此标志的情况下获得 MySQL “on update timestamp”,必须显式呈现上述 DDL。此外,相同的 DDL 也适用于 DATETIME 数据类型。

SQLAlchemy 的 MySQL 方言尚未提供生成 MySQL 的 “ON UPDATE CURRENT_TIMESTAMP” 子句的选项,并指出这不是通用的 “ON UPDATE”,因为标准 SQL 中没有这样的语法。SQLAlchemy 的 Column.server_onupdate 参数目前与此特殊的 MySQL 行为无关。

要生成此 DDL,请使用 Column.server_default 参数并传递一个文本子句,其中还包括 ON UPDATE 子句。

from sqlalchemy import Table, MetaData, Column, Integer, String, TIMESTAMP
from sqlalchemy import text

metadata = MetaData()

mytable = Table(
    "mytable",
    metadata,
    Column("id", Integer, primary_key=True),
    Column("data", String(50)),
    Column(
        "last_updated",
        TIMESTAMP,
        server_default=text(
            "CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
        ),
    ),
)

相同的说明适用于 DateTimeDATETIME 数据类型的使用。

from sqlalchemy import DateTime

mytable = Table(
    "mytable",
    metadata,
    Column("id", Integer, primary_key=True),
    Column("data", String(50)),
    Column(
        "last_updated",
        DateTime,
        server_default=text(
            "CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
        ),
    ),
)

即使 Column.server_onupdate 功能不生成此 DDL,但仍然可能希望向 ORM 发出信号,表明应获取此更新的值。此语法如下所示:

from sqlalchemy.schema import FetchedValue


class MyClass(Base):
    __tablename__ = "mytable"

    id = Column(Integer, primary_key=True)
    data = Column(String(50))
    last_updated = Column(
        TIMESTAMP,
        server_default=text(
            "CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
        ),
        server_onupdate=FetchedValue(),
    )

TIMESTAMP 列和 NULL

MySQL 历史上强制规定,指定 TIMESTAMP 数据类型的列隐式包含 CURRENT_TIMESTAMP 的默认值(即使未声明),并且还将列设置为 NOT NULL,这与所有其他数据类型的行为相反。

mysql> CREATE TABLE ts_test (
    -> a INTEGER,
    -> b INTEGER NOT NULL,
    -> c TIMESTAMP,
    -> d TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    -> e TIMESTAMP NULL);
Query OK, 0 rows affected (0.03 sec)

mysql> SHOW CREATE TABLE ts_test;
+---------+-----------------------------------------------------
| Table   | Create Table
+---------+-----------------------------------------------------
| ts_test | CREATE TABLE `ts_test` (
  `a` int(11) DEFAULT NULL,
  `b` int(11) NOT NULL,
  `c` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `d` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `e` timestamp NULL DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1

上面,我们看到 INTEGER 列默认为 NULL,除非将其指定为 NOT NULL。但是,当列的类型为 TIMESTAMP 时,会生成 CURRENT_TIMESTAMP 的隐式默认值,这也强制将列设为 NOT NULL,即使我们没有将其指定为 NOT NULL。

可以使用 MySQL 5.6 中引入的 explicit_defaults_for_timestamp 配置标志在 MySQL 端更改 MySQL 的此行为。启用此服务器设置后,TIMESTAMP 列在 MySQL 端关于默认值和可空性的行为与其他任何数据类型相同。

但是,为了适应绝大多数未指定此新标志的 MySQL 数据库,SQLAlchemy 为任何未指定 nullable=False 的 TIMESTAMP 列显式发出 “NULL” 说明符。为了适应指定了 explicit_defaults_for_timestamp 的较新数据库,SQLAlchemy 也为指定了 nullable=False 的 TIMESTAMP 列发出 NOT NULL。以下示例说明了这一点:

from sqlalchemy import MetaData, Integer, Table, Column, text
from sqlalchemy.dialects.mysql import TIMESTAMP

m = MetaData()
t = Table(
    "ts_test",
    m,
    Column("a", Integer),
    Column("b", Integer, nullable=False),
    Column("c", TIMESTAMP),
    Column("d", TIMESTAMP, nullable=False),
)


from sqlalchemy import create_engine

e = create_engine("mysql+mysqldb://scott:tiger@localhost/test", echo=True)
m.create_all(e)

输出

CREATE TABLE ts_test (
    a INTEGER,
    b INTEGER NOT NULL,
    c TIMESTAMP NULL,
    d TIMESTAMP NOT NULL
)

MySQL SQL 构造

对象名称 描述

match

生成 MATCH (X, Y) AGAINST ('TEXT') 子句。

class sqlalchemy.dialects.mysql.match

生成 MATCH (X, Y) AGAINST ('TEXT') 子句。

例如:

from sqlalchemy import desc
from sqlalchemy.dialects.mysql import match

match_expr = match(
    users_table.c.firstname,
    users_table.c.lastname,
    against="Firstname Lastname",
)

stmt = (
    select(users_table)
    .where(match_expr.in_boolean_mode())
    .order_by(desc(match_expr))
)

将生成类似于以下内容的 SQL:

SELECT id, firstname, lastname
FROM user
WHERE MATCH(firstname, lastname) AGAINST (:param_1 IN BOOLEAN MODE)
ORDER BY MATCH(firstname, lastname) AGAINST (:param_2) DESC

match() 函数是所有 SQL 表达式上可用的 ColumnElement.match() 方法的独立版本,就像使用 ColumnElement.match() 时一样,但允许传递多个列。

参数:
  • cols – 要匹配的列表达式

  • against – 要比较的表达式

  • in_boolean_mode – 布尔值,将 “boolean mode” 设置为 true

  • in_natural_language_mode – 布尔值,将 “natural language” 设置为 true

  • with_query_expansion – 布尔值,将 “query expansion” 设置为 true

版本 1.4.19 新增。

另请参阅

ColumnElement.match()

类签名

class sqlalchemy.dialects.mysql.match (sqlalchemy.sql.expression.Generative, sqlalchemy.sql.expression.BinaryExpression)

method sqlalchemy.dialects.mysql.match.in_boolean_mode() Self

将 “IN BOOLEAN MODE” 修饰符应用于 MATCH 表达式。

返回值:

一个新的 match 实例,应用了修改。

method sqlalchemy.dialects.mysql.match.in_natural_language_mode() Self

将 “IN NATURAL LANGUAGE MODE” 修饰符应用于 MATCH 表达式。

返回值:

一个新的 match 实例,应用了修改。

attribute sqlalchemy.dialects.mysql.match.inherit_cache: bool | None = True

指示此 HasCacheKey 实例是否应使用其直接超类使用的缓存键生成方案。

该属性默认为 None,表示构造尚未考虑其是否适合参与缓存;这在功能上等同于将值设置为 False,但也会发出警告。

如果与对象对应的 SQL 不会根据此类的本地属性(而不是其超类)而更改,则可以在特定类上将此标志设置为 True

另请参阅

为自定义构造启用缓存支持 - 关于为第三方或用户定义的 SQL 构造设置 HasCacheKey.inherit_cache 属性的一般指南。

method sqlalchemy.dialects.mysql.match.with_query_expansion() Self

将 “WITH QUERY EXPANSION” 修饰符应用于 MATCH 表达式。

返回值:

一个新的 match 实例,应用了修改。

MySQL 数据类型

与所有 SQLAlchemy 方言一样,所有已知对 MySQL 有效的大写类型都可以从顶层方言导入。

from sqlalchemy.dialects.mysql import (
    BIGINT,
    BINARY,
    BIT,
    BLOB,
    BOOLEAN,
    CHAR,
    DATE,
    DATETIME,
    DECIMAL,
    DECIMAL,
    DOUBLE,
    ENUM,
    FLOAT,
    INTEGER,
    LONGBLOB,
    LONGTEXT,
    MEDIUMBLOB,
    MEDIUMINT,
    MEDIUMTEXT,
    NCHAR,
    NUMERIC,
    NVARCHAR,
    REAL,
    SET,
    SMALLINT,
    TEXT,
    TIME,
    TIMESTAMP,
    TINYBLOB,
    TINYINT,
    TINYTEXT,
    VARBINARY,
    VARCHAR,
    YEAR,
)

除了上述类型外,MariaDB 还支持以下类型:

from sqlalchemy.dialects.mysql import (
    INET4,
    INET6,
)

特定于 MySQL 或 MariaDB,或具有特定构造参数的类型如下:

对象名称 描述

BIGINT

MySQL BIGINTEGER 类型。

BIT

MySQL BIT 类型。

CHAR

MySQL CHAR 类型,用于固定长度的字符数据。

DATETIME

MySQL DATETIME 类型。

DECIMAL

MySQL DECIMAL 类型。

ENUM

MySQL ENUM 类型。

FLOAT

MySQL FLOAT 类型。

INET4

MariaDB 的 INET4 列类型

INET6

MariaDB 的 INET6 列类型

INTEGER

MySQL INTEGER 类型。

JSON

MySQL JSON 类型。

LONGBLOB

MySQL LONGBLOB 类型,用于最大 2^32 字节的二进制数据。

LONGTEXT

MySQL LONGTEXT 类型,用于最大 2^32 字节编码的字符存储。

MEDIUMBLOB

MySQL MEDIUMBLOB 类型,用于最大 2^24 字节的二进制数据。

MEDIUMINT

MySQL MEDIUMINTEGER 类型。

MEDIUMTEXT

MySQL MEDIUMTEXT 类型,用于最大 2^24 字节编码的字符存储。

NCHAR

MySQL NCHAR 类型。

NUMERIC

MySQL NUMERIC 类型。

NVARCHAR

MySQL NVARCHAR 类型。

REAL

MySQL REAL 类型。

SET

MySQL SET 类型。

SMALLINT

MySQL SMALLINTEGER 类型。

TIME

MySQL TIME 类型。

TIMESTAMP

MySQL TIMESTAMP 类型。

TINYBLOB

MySQL TINYBLOB 类型,用于最大 2^8 字节的二进制数据。

TINYINT

MySQL TINYINT 类型。

TINYTEXT

MySQL TINYTEXT 类型,用于最大 2^8 字节编码的字符存储。

VARCHAR

MySQL VARCHAR 类型,用于可变长度的字符数据。

YEAR

MySQL YEAR 类型,用于存储 1901-2155 年的单字节存储。

class sqlalchemy.dialects.mysql.BIGINT

MySQL BIGINTEGER 类型。

成员

__init__()

类签名

class sqlalchemy.dialects.mysql.BIGINT (sqlalchemy.dialects.mysql.types._IntegerType, sqlalchemy.types.BIGINT)

method sqlalchemy.dialects.mysql.BIGINT.__init__(display_width=None, **kw)

构造一个 BIGINTEGER。

参数:
  • display_width – 可选,此数字的最大显示宽度。

  • unsigned – 布尔值,可选。

  • zerofill – 可选。如果为 true,则值将存储为左侧用零填充的字符串。请注意,这不会影响底层数据库 API 返回的值,这些值仍然是数字。

class sqlalchemy.dialects.mysql.BINARY

SQL BINARY 类型。

类签名

class sqlalchemy.dialects.mysql.BINARY (sqlalchemy.types._Binary)

class sqlalchemy.dialects.mysql.BIT

MySQL BIT 类型。

此类型适用于 MySQL 5.0.3 或更高版本(对于 MyISAM),以及 5.0.5 或更高版本(对于 MyISAM、MEMORY、InnoDB 和 BDB)。对于旧版本,请使用 MSTinyInteger() 类型。

成员

__init__()

method sqlalchemy.dialects.mysql.BIT.__init__(length=None)

构造一个 BIT。

参数:

length – 可选,位数。

class sqlalchemy.dialects.mysql.BLOB

SQL BLOB 类型。

类签名

class sqlalchemy.dialects.mysql.BLOB (sqlalchemy.types.LargeBinary)

method sqlalchemy.dialects.mysql.BLOB.__init__(length: int | None = None)

继承自 sqlalchemy.types.LargeBinary.__init__ 方法,该方法属于 LargeBinary

构造一个 LargeBinary 类型。

参数:

length – 可选参数,用于 DDL 语句中列的长度,适用于接受长度的二进制类型,例如 MySQL BLOB 类型。

class sqlalchemy.dialects.mysql.BOOLEAN

SQL BOOLEAN 类型。

类签名

class sqlalchemy.dialects.mysql.BOOLEAN (sqlalchemy.types.Boolean)

method sqlalchemy.dialects.mysql.BOOLEAN.__init__(create_constraint: bool = False, name: str | None = None, _create_events: bool = True, _adapted_from: SchemaType | None = None)

继承自 sqlalchemy.types.Boolean.__init__ 方法,该方法属于 Boolean

构造一个 Boolean 类型。

参数:
  • create_constraint

    默认为 False。如果 boolean 类型生成为 int/smallint,则还在表上创建一个 CHECK 约束,以确保值为 1 或 0。

    注意

    强烈建议 CHECK 约束具有显式名称,以便支持模式管理问题。这可以通过设置 Boolean.name 参数或设置适当的命名约定来建立;有关背景信息,请参阅 配置约束命名约定

    在版本 1.4 中变更:- 此标志现在默认为 False,这意味着对于非原生枚举类型,不会生成 CHECK 约束。

  • name – 如果生成 CHECK 约束,请指定约束的名称。

class sqlalchemy.dialects.mysql.CHAR

MySQL CHAR 类型,用于固定长度的字符数据。

成员

__init__()

类签名

class sqlalchemy.dialects.mysql.CHAR (sqlalchemy.dialects.mysql.types._StringType, sqlalchemy.types.CHAR)

method sqlalchemy.dialects.mysql.CHAR.__init__(length=None, **kwargs)

构造一个 CHAR 类型。

参数:
  • length – 最大数据长度,以字符为单位。

  • binary – 可选参数,为国家字符集使用默认的二进制排序规则。这不会影响存储的数据类型,请使用 BINARY 类型存储二进制数据。

  • collation – 可选参数,请求特定的排序规则。必须与国家字符集兼容。

class sqlalchemy.dialects.mysql.DATE

SQL DATE 类型。

类签名

class sqlalchemy.dialects.mysql.DATE (sqlalchemy.types.Date)

class sqlalchemy.dialects.mysql.DATETIME

MySQL DATETIME 类型。

成员

__init__()

method sqlalchemy.dialects.mysql.DATETIME.__init__(timezone=False, fsp=None)

构造一个 MySQL DATETIME 类型。

参数:
  • timezone – MySQL 方言未使用。

  • fsp

    小数秒精度值。MySQL 5.6.4 支持存储小数秒;此参数将在为 DATETIME 类型发出 DDL 时使用。

    注意

    DBAPI 驱动程序对小数秒的支持可能有限;当前支持包括 MySQL Connector/Python。

class sqlalchemy.dialects.mysql.DECIMAL

MySQL DECIMAL 类型。

成员

__init__()

类签名

class sqlalchemy.dialects.mysql.DECIMAL (sqlalchemy.dialects.mysql.types._NumericType, sqlalchemy.types.DECIMAL)

method sqlalchemy.dialects.mysql.DECIMAL.__init__(precision=None, scale=None, asdecimal=True, **kw)

构造一个 DECIMAL 类型。

参数:
  • precision – 此数字的总位数。如果 scale 和 precision 都为 None,则值将存储在服务器允许的限制范围内。

  • scale – 小数点后的位数。

  • unsigned – 一个布尔值,可选。

  • zerofill – 可选。如果为 true,则值将作为字符串存储,并在左侧填充零。请注意,这不会影响底层数据库 API 返回的值,这些值仍然是数字。

class sqlalchemy.dialects.mysql.DOUBLE

MySQL DOUBLE 类型。

类签名

class sqlalchemy.dialects.mysql.DOUBLE (sqlalchemy.dialects.mysql.types._FloatType, sqlalchemy.types.DOUBLE)

method sqlalchemy.dialects.mysql.DOUBLE.__init__(precision=None, scale=None, asdecimal=True, **kw)

构造一个 DOUBLE 类型。

注意

DOUBLE 类型默认将 float 转换为 Decimal,使用截断,默认截断为 10 位数字。指定 scale=ndecimal_return_scale=n 以更改此比例,或指定 asdecimal=False 以直接将值作为 Python 浮点数返回。

参数:
  • precision – 此数字的总位数。如果 scale 和 precision 都为 None,则值将存储在服务器允许的限制范围内。

  • scale – 小数点后的位数。

  • unsigned – 一个布尔值,可选。

  • zerofill – 可选。如果为 true,则值将作为字符串存储,并在左侧填充零。请注意,这不会影响底层数据库 API 返回的值,这些值仍然是数字。

class sqlalchemy.dialects.mysql.ENUM

MySQL ENUM 类型。

成员

__init__()

类签名

class sqlalchemy.dialects.mysql.ENUM (sqlalchemy.types.NativeForEmulated, sqlalchemy.types.Enum, sqlalchemy.dialects.mysql.types._StringType)

method sqlalchemy.dialects.mysql.ENUM.__init__(*enums, **kw)

构造一个 ENUM 类型。

例如:

Column("myenum", ENUM("foo", "bar", "baz"))
参数:
  • enums

    此 ENUM 的有效值范围。enums 中的值不带引号,在生成模式时,它们将被转义并用单引号括起来。此对象也可以是符合 PEP-435 规范的枚举类型。

  • strict

    此标志无效。

    在版本 The 中变更:MySQL ENUM 类型以及基本 Enum 类型现在验证所有 Python 数据值。

  • charset – 可选参数,此字符串值的列级字符集。优先于 'ascii' 或 'unicode' 简写形式。

  • collation – 可选参数,此字符串值的列级排序规则。优先于 'binary' 简写形式。

  • ascii – 默认为 False:'latin1' 字符集的简写形式,在模式中生成 ASCII。

  • unicode – 默认为 False:'ucs2' 字符集的简写形式,在模式中生成 UNICODE。

  • binary – 默认为 False:简写形式,选择与列字符集匹配的二进制排序规则类型。在模式中生成 BINARY。这不会影响存储的数据类型,只会影响字符数据的排序规则。

class sqlalchemy.dialects.mysql.FLOAT

MySQL FLOAT 类型。

成员

__init__()

类签名

class sqlalchemy.dialects.mysql.FLOAT (sqlalchemy.dialects.mysql.types._FloatType, sqlalchemy.types.FLOAT)

method sqlalchemy.dialects.mysql.FLOAT.__init__(precision=None, scale=None, asdecimal=False, **kw)

构造一个 FLOAT 类型。

参数:
  • precision – 此数字的总位数。如果 scale 和 precision 都为 None,则值将存储在服务器允许的限制范围内。

  • scale – 小数点后的位数。

  • unsigned – 一个布尔值,可选。

  • zerofill – 可选。如果为 true,则值将作为字符串存储,并在左侧填充零。请注意,这不会影响底层数据库 API 返回的值,这些值仍然是数字。

class sqlalchemy.dialects.mysql.INET4

MariaDB 的 INET4 列类型

2.0.37 版本新增。

class sqlalchemy.dialects.mysql.INET6

MariaDB 的 INET6 列类型

2.0.37 版本新增。

class sqlalchemy.dialects.mysql.INTEGER

MySQL INTEGER 类型。

成员

__init__()

类签名

class sqlalchemy.dialects.mysql.INTEGER (sqlalchemy.dialects.mysql.types._IntegerType, sqlalchemy.types.INTEGER)

method sqlalchemy.dialects.mysql.INTEGER.__init__(display_width=None, **kw)

构造一个 INTEGER 类型。

参数:
  • display_width – 可选参数,此数字的最大显示宽度。

  • unsigned – 一个布尔值,可选。

  • zerofill – 可选。如果为 true,则值将作为字符串存储,并在左侧填充零。请注意,这不会影响底层数据库 API 返回的值,这些值仍然是数字。

class sqlalchemy.dialects.mysql.JSON

MySQL JSON 类型。

MySQL 从 5.7 版本开始支持 JSON。MariaDB 从 10.2 版本开始支持 JSON(作为 LONGTEXT 的别名)。

当对 MySQL 或 MariaDB 后端使用基本 JSON 数据类型时,会自动使用 JSON

另请参阅

JSON - 通用跨平台 JSON 数据类型的主要文档。

JSON 类型支持 JSON 值的持久化以及 JSON 数据类型提供的核心索引操作,通过调整操作以在数据库级别呈现 JSON_EXTRACT 函数。

class sqlalchemy.dialects.mysql.LONGBLOB

MySQL LONGBLOB 类型,用于最大 2^32 字节的二进制数据。

类签名

class sqlalchemy.dialects.mysql.LONGBLOB (sqlalchemy.types._Binary)

class sqlalchemy.dialects.mysql.LONGTEXT

MySQL LONGTEXT 类型,用于最大 2^32 字节编码的字符存储。

成员

__init__()

类签名

class sqlalchemy.dialects.mysql.LONGTEXT (sqlalchemy.dialects.mysql.types._StringType)

method sqlalchemy.dialects.mysql.LONGTEXT.__init__(**kwargs)

构造一个 LONGTEXT 类型。

参数:
  • charset – 可选参数,此字符串值的列级字符集。优先于 'ascii' 或 'unicode' 简写形式。

  • collation – 可选参数,此字符串值的列级排序规则。优先于 'binary' 简写形式。

  • ascii – 默认为 False:'latin1' 字符集的简写形式,在模式中生成 ASCII。

  • unicode – 默认为 False:'ucs2' 字符集的简写形式,在模式中生成 UNICODE。

  • national – 可选。如果为 true,则使用服务器配置的国家字符集。

  • binary – 默认为 False:简写形式,选择与列字符集匹配的二进制排序规则类型。在模式中生成 BINARY。这不会影响存储的数据类型,只会影响字符数据的排序规则。

class sqlalchemy.dialects.mysql.MEDIUMBLOB

MySQL MEDIUMBLOB 类型,用于最大 2^24 字节的二进制数据。

类签名

class sqlalchemy.dialects.mysql.MEDIUMBLOB (sqlalchemy.types._Binary)

class sqlalchemy.dialects.mysql.MEDIUMINT

MySQL MEDIUMINTEGER 类型。

成员

__init__()

类签名

class sqlalchemy.dialects.mysql.MEDIUMINT (sqlalchemy.dialects.mysql.types._IntegerType)

method sqlalchemy.dialects.mysql.MEDIUMINT.__init__(display_width=None, **kw)

构造一个 MEDIUMINTEGER。

参数:
  • display_width – 可选参数,此数字的最大显示宽度。

  • unsigned – 一个布尔值,可选参数。

  • zerofill – 可选参数。如果为 true,值将存储为左侧用零填充的字符串。请注意,这不会影响底层数据库 API 返回的值,这些值仍然是数值。

class sqlalchemy.dialects.mysql.MEDIUMTEXT

MySQL MEDIUMTEXT 类型,用于最大 2^24 字节编码的字符存储。

成员

__init__()

类签名

class sqlalchemy.dialects.mysql.MEDIUMTEXT (sqlalchemy.dialects.mysql.types._StringType)

method sqlalchemy.dialects.mysql.MEDIUMTEXT.__init__(**kwargs)

构造一个 MEDIUMTEXT。

参数:
  • charset – 可选参数,此字符串值的列级字符集。优先于 ‘ascii’ 或 ‘unicode’ 简写。

  • collation – 可选参数,此字符串值的列级排序规则。优先于 ‘binary’ 简写。

  • ascii – 默认为 False:‘latin1’ 字符集的简写,在 schema 中生成 ASCII。

  • unicode – 默认为 False:‘ucs2’ 字符集的简写,在 schema 中生成 UNICODE。

  • national – 可选参数。如果为 true,则使用服务器配置的国家字符集。

  • binary – 默认为 False:简写,选择与列字符集匹配的二进制排序规则类型。在 schema 中生成 BINARY。这不会影响存储的数据类型,仅影响字符数据的排序规则。

class sqlalchemy.dialects.mysql.NCHAR

MySQL NCHAR 类型。

用于服务器配置的国家字符集中的固定长度字符数据。

成员

__init__()

类签名

class sqlalchemy.dialects.mysql.NCHAR (sqlalchemy.dialects.mysql.types._StringType, sqlalchemy.types.NCHAR)

method sqlalchemy.dialects.mysql.NCHAR.__init__(length=None, **kwargs)

构造一个 NCHAR。

参数:
  • length – 最大数据长度,以字符为单位。

  • binary – 可选参数,对国家字符集使用默认的二进制排序规则。这不会影响存储的数据类型,对于二进制数据请使用 BINARY 类型。

  • collation – 可选参数,请求特定的排序规则。必须与国家字符集兼容。

class sqlalchemy.dialects.mysql.NUMERIC

MySQL NUMERIC 类型。

成员

__init__()

类签名

class sqlalchemy.dialects.mysql.NUMERIC (sqlalchemy.dialects.mysql.types._NumericType, sqlalchemy.types.NUMERIC)

method sqlalchemy.dialects.mysql.NUMERIC.__init__(precision=None, scale=None, asdecimal=True, **kw)

构造一个 NUMERIC。

参数:
  • precision – 此数字的总位数。如果 scale 和 precision 均为 None,则值将存储到服务器允许的限制。

  • scale – 小数点后的位数。

  • unsigned – 一个布尔值,可选参数。

  • zerofill – 可选参数。如果为 true,值将存储为左侧用零填充的字符串。请注意,这不会影响底层数据库 API 返回的值,这些值仍然是数值。

class sqlalchemy.dialects.mysql.NVARCHAR

MySQL NVARCHAR 类型。

用于服务器配置的国家字符集中的可变长度字符数据。

成员

__init__()

类签名

class sqlalchemy.dialects.mysql.NVARCHAR (sqlalchemy.dialects.mysql.types._StringType, sqlalchemy.types.NVARCHAR)

method sqlalchemy.dialects.mysql.NVARCHAR.__init__(length=None, **kwargs)

构造一个 NVARCHAR。

参数:
  • length – 最大数据长度,以字符为单位。

  • binary – 可选参数,对国家字符集使用默认的二进制排序规则。这不会影响存储的数据类型,对于二进制数据请使用 BINARY 类型。

  • collation – 可选参数,请求特定的排序规则。必须与国家字符集兼容。

class sqlalchemy.dialects.mysql.REAL

MySQL REAL 类型。

成员

__init__()

类签名

class sqlalchemy.dialects.mysql.REAL (sqlalchemy.dialects.mysql.types._FloatType, sqlalchemy.types.REAL)

method sqlalchemy.dialects.mysql.REAL.__init__(precision=None, scale=None, asdecimal=True, **kw)

构造一个 REAL。

注意

默认情况下,REAL 类型将 float 转换为 Decimal,使用截断,默认截断为 10 位数字。指定 scale=ndecimal_return_scale=n 以更改此比例,或 asdecimal=False 以将值直接作为 Python 浮点数返回。

参数:
  • precision – 此数字的总位数。如果 scale 和 precision 均为 None,则值将存储到服务器允许的限制。

  • scale – 小数点后的位数。

  • unsigned – 一个布尔值,可选参数。

  • zerofill – 可选参数。如果为 true,值将存储为左侧用零填充的字符串。请注意,这不会影响底层数据库 API 返回的值,这些值仍然是数值。

class sqlalchemy.dialects.mysql.SET

MySQL SET 类型。

成员

__init__()

类签名

class sqlalchemy.dialects.mysql.SET (sqlalchemy.dialects.mysql.types._StringType)

method sqlalchemy.dialects.mysql.SET.__init__(*values, **kw)

构造一个 SET。

例如:

Column("myset", SET("foo", "bar", "baz"))

如果此集合将用于为表生成 DDL,或者如果 SET.retrieve_as_bitwise 标志设置为 True,则需要潜在值的列表。

参数:
  • values – 此 SET 的有效值范围。这些值不带引号,在生成 schema 时将被转义并用单引号括起来。

  • convert_unicode – 与 String.convert_unicode 的标志相同。

  • collation – 与 String.collation 的标志相同

  • charset – 与 VARCHAR.charset 的标志相同。

  • ascii – 与 VARCHAR.ascii 的标志相同。

  • unicode – 与 VARCHAR.unicode 的标志相同。

  • binary – 与 VARCHAR.binary 的标志相同。

  • retrieve_as_bitwise

    如果为 True,则 set 类型的数据将使用整数值持久化和选择,其中 set 被强制转换为用于持久化的按位掩码。 MySQL 允许此模式,该模式的优点是能够明确地存储值,例如空字符串 ''。数据类型在 SELECT 语句中将显示为表达式 col + 0,以便将值强制转换为结果集中的整数值。如果希望持久化可以存储空字符串 '' 作为值的集合,则需要此标志。

    警告

    当使用 SET.retrieve_as_bitwise 时,至关重要的是,集合值的列表的表达顺序必须与 MySQL 数据库中存在的顺序完全相同

class sqlalchemy.dialects.mysql.SMALLINT

MySQL SMALLINTEGER 类型。

成员

__init__()

类签名

class sqlalchemy.dialects.mysql.SMALLINT (sqlalchemy.dialects.mysql.types._IntegerType, sqlalchemy.types.SMALLINT)

method sqlalchemy.dialects.mysql.SMALLINT.__init__(display_width=None, **kw)

构造一个 SMALLINTEGER。

参数:
  • display_width – 可选参数,此数字的最大显示宽度。

  • unsigned – 一个布尔值,可选参数。

  • zerofill – 可选参数。如果为 true,值将存储为左侧用零填充的字符串。请注意,这不会影响底层数据库 API 返回的值,这些值仍然是数值。

class sqlalchemy.dialects.mysql.TEXT

MySQL TEXT 类型,用于字符存储,编码最多为 2^16 字节。

类签名

class sqlalchemy.dialects.mysql.TEXT (sqlalchemy.dialects.mysql.types._StringType, sqlalchemy.types.TEXT)

method sqlalchemy.dialects.mysql.TEXT.__init__(length=None, **kw)

构造一个 TEXT。

参数:
  • length – 可选参数,如果提供,服务器可以通过替换足以存储 length 字节字符的最小 TEXT 类型来优化存储。

  • charset – 可选参数,此字符串值的列级字符集。优先于 ‘ascii’ 或 ‘unicode’ 简写。

  • collation – 可选参数,此字符串值的列级排序规则。优先于 ‘binary’ 简写。

  • ascii – 默认为 False:‘latin1’ 字符集的简写,在 schema 中生成 ASCII。

  • unicode – 默认为 False:‘ucs2’ 字符集的简写,在 schema 中生成 UNICODE。

  • national – 可选参数。如果为 true,则使用服务器配置的国家字符集。

  • binary – 默认为 False:简写,选择与列字符集匹配的二进制排序规则类型。在 schema 中生成 BINARY。这不会影响存储的数据类型,仅影响字符数据的排序规则。

class sqlalchemy.dialects.mysql.TIME

MySQL TIME 类型。

成员

__init__()

method sqlalchemy.dialects.mysql.TIME.__init__(timezone=False, fsp=None)

构造一个 MySQL TIME 类型。

参数:
  • timezone – MySQL 方言未使用。

  • fsp

    小数秒精度值。 MySQL 5.6 支持存储小数秒;在为 TIME 类型发出 DDL 时将使用此参数。

    注意

    DBAPI 驱动程序对小数秒的支持可能有限;当前支持包括 MySQL Connector/Python。

class sqlalchemy.dialects.mysql.TIMESTAMP

MySQL TIMESTAMP 类型。

成员

__init__()

method sqlalchemy.dialects.mysql.TIMESTAMP.__init__(timezone=False, fsp=None)

构造一个 MySQL TIMESTAMP 类型。

参数:
  • timezone – MySQL 方言未使用。

  • fsp

    小数秒精度值。 MySQL 5.6.4 支持存储小数秒;在为 TIMESTAMP 类型发出 DDL 时将使用此参数。

    注意

    DBAPI 驱动程序对小数秒的支持可能有限;当前支持包括 MySQL Connector/Python。

class sqlalchemy.dialects.mysql.TINYBLOB

MySQL TINYBLOB 类型,用于最大 2^8 字节的二进制数据。

类签名

class sqlalchemy.dialects.mysql.TINYBLOB (sqlalchemy.types._Binary)

class sqlalchemy.dialects.mysql.TINYINT

MySQL TINYINT 类型。

成员

__init__()

类签名

class sqlalchemy.dialects.mysql.TINYINT (sqlalchemy.dialects.mysql.types._IntegerType)

method sqlalchemy.dialects.mysql.TINYINT.__init__(display_width=None, **kw)

构造一个 TINYINT。

参数:
  • display_width – 可选参数,此数字的最大显示宽度。

  • unsigned – 一个布尔值,可选参数。

  • zerofill – 可选参数。如果为 true,值将存储为左侧用零填充的字符串。请注意,这不会影响底层数据库 API 返回的值,这些值仍然是数值。

class sqlalchemy.dialects.mysql.TINYTEXT

MySQL TINYTEXT 类型,用于最大 2^8 字节编码的字符存储。

成员

__init__()

类签名

class sqlalchemy.dialects.mysql.TINYTEXT (sqlalchemy.dialects.mysql.types._StringType)

method sqlalchemy.dialects.mysql.TINYTEXT.__init__(**kwargs)

构造一个 TINYTEXT。

参数:
  • charset – 可选参数,此字符串值的列级字符集。优先于 ‘ascii’ 或 ‘unicode’ 简写。

  • collation – 可选参数,此字符串值的列级排序规则。优先于 ‘binary’ 简写。

  • ascii – 默认为 False:‘latin1’ 字符集的简写,在 schema 中生成 ASCII。

  • unicode – 默认为 False:‘ucs2’ 字符集的简写,在 schema 中生成 UNICODE。

  • national – 可选参数。如果为 true,则使用服务器配置的国家字符集。

  • binary – 默认为 False:简写,选择与列字符集匹配的二进制排序规则类型。在 schema 中生成 BINARY。这不会影响存储的数据类型,仅影响字符数据的排序规则。

class sqlalchemy.dialects.mysql.VARBINARY

SQL VARBINARY 类型。

类签名

class sqlalchemy.dialects.mysql.VARBINARY (sqlalchemy.types._Binary)

class sqlalchemy.dialects.mysql.VARCHAR

MySQL VARCHAR 类型,用于可变长度的字符数据。

成员

__init__()

类签名

class sqlalchemy.dialects.mysql.VARCHAR (sqlalchemy.dialects.mysql.types._StringType, sqlalchemy.types.VARCHAR)

method sqlalchemy.dialects.mysql.VARCHAR.__init__(length=None, **kwargs)

构造一个 VARCHAR。

参数:
  • charset(字符集) – 可选参数,此字符串值的列级字符集。优先于 ‘ascii’ 或 ‘unicode’ 简写。

  • collation(排序规则) – 可选参数,此字符串值的列级排序规则。优先于 ‘binary’ 简写。

  • ascii – 默认为 False:latin1 字符集的简写,在 schema 中生成 ASCII。

  • unicode – 默认为 False:ucs2 字符集的简写,在 schema 中生成 UNICODE。

  • national(国家字符集) – 可选参数。如果为 true,则使用服务器配置的国家字符集。

  • binary(二进制) – 默认为 False:简写,选择与列字符集匹配的二进制排序规则类型。在 schema 中生成 BINARY。这不影响存储的数据类型,仅影响字符数据的排序规则。

class sqlalchemy.dialects.mysql.YEAR

MySQL YEAR 类型,用于存储 1901-2155 年的单字节存储。

MySQL DML 构造

对象名称 描述

insert(table)

构造一个 MySQL/MariaDB 特定的变体 Insert 构造。

Insert

MySQL 特有的 INSERT 实现。

function sqlalchemy.dialects.mysql.insert(table: _DMLTableArgument) Insert

构造一个 MySQL/MariaDB 特定的变体 Insert 构造。

sqlalchemy.dialects.mysql.insert() 函数创建一个 sqlalchemy.dialects.mysql.Insert。此类基于与方言无关的 Insert 构造,该构造可以使用 SQLAlchemy Core 中的 insert() 函数构造。

Insert 构造包含额外的方法 Insert.on_duplicate_key_update()

class sqlalchemy.dialects.mysql.Insert

MySQL 特有的 INSERT 实现。

为 MySQL 特定的语法(例如 ON DUPLICATE KEY UPDATE)添加方法。

Insert 对象是使用 sqlalchemy.dialects.mysql.insert() 函数创建的。

1.2 版本新增。

attribute sqlalchemy.dialects.mysql.Insert.inherit_cache: bool | None = False

指示此 HasCacheKey 实例是否应使用其直接超类使用的缓存键生成方案。

该属性默认为 None,表示构造尚未考虑其是否适合参与缓存;这在功能上等同于将值设置为 False,但也会发出警告。

如果与对象对应的 SQL 不会根据此类的本地属性(而不是其超类)而更改,则可以在特定类上将此标志设置为 True

另请参阅

为自定义构造启用缓存支持 - 关于为第三方或用户定义的 SQL 构造设置 HasCacheKey.inherit_cache 属性的一般指南。

attribute sqlalchemy.dialects.mysql.Insert.inserted

为 ON DUPLICATE KEY UPDATE 语句提供 “inserted” 命名空间

MySQL 的 ON DUPLICATE KEY UPDATE 子句允许通过名为 VALUES() 的特殊函数引用将要插入的行。此属性提供此行中的所有列以供引用,以便它们将在 ON DUPLICATE KEY UPDATE 子句内的 VALUES() 函数中呈现。该属性被命名为 .inserted,以避免与现有的 Insert.values() 方法冲突。

提示

Insert.inserted 属性是 ColumnCollection 的一个实例,它提供的接口与 Table.c 集合相同,如 访问表和列 中所述。使用此集合,可以使用像属性一样的普通名称(例如 stmt.inserted.some_column),但特殊名称和字典方法名称应使用索引访问,例如 stmt.inserted["column name"]stmt.inserted["values"]。有关更多示例,请参阅 ColumnCollection 的文档字符串。

另请参阅

INSERT…ON DUPLICATE KEY UPDATE (Upsert) - 如何使用 Insert.inserted 的示例

method sqlalchemy.dialects.mysql.Insert.on_duplicate_key_update(*args: Mapping[Any, Any] | List[Tuple[str, Any]] | ColumnCollection[Any, Any], **kw: Any) Self

指定 ON DUPLICATE KEY UPDATE 子句。

参数:

**kw – 链接到 UPDATE 值的列键。这些值可以是任何 SQL 表达式或支持的字面 Python 值。

警告

此字典**不**考虑 Python 指定的默认 UPDATE 值或生成函数,例如使用 Column.onupdate 指定的那些。这些值不会为 ON DUPLICATE KEY UPDATE 样式的 UPDATE 执行,除非在此处手动指定值。

参数:

*args

作为传递键/值参数的替代方法,可以传递字典或 2 元组列表作为单个位置参数。

传递单个字典等效于关键字参数形式

insert().on_duplicate_key_update({"name": "some name"})

传递 2 元组列表表示 UPDATE 子句中的参数赋值应按发送顺序排列,其方式类似于 Update 构造在 参数排序的更新 中描述的方式

insert().on_duplicate_key_update(
    [
        ("name", "some name"),
        ("value", "some value"),
    ]
)

在 1.3 版本中变更:参数可以指定为字典或 2 元组列表;后一种形式提供了参数排序。

1.2 版本新增。

mysqlclient(MySQL-Python 的分支)

通过 mysqlclient(MySQL-Python 的维护分支)驱动程序支持 MySQL / MariaDB 数据库。

DBAPI

有关 mysqlclient(MySQL-Python 的维护分支)的文档和下载信息(如果适用)可在以下网址获取:https://pypi.ac.cn/project/mysqlclient/

连接

连接字符串

mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>

驱动程序状态

mysqlclient DBAPI 是 MySQL-Python DBAPI 的维护分支,后者已不再维护。mysqlclient 支持 Python 2 和 Python 3,并且非常稳定。

Unicode

有关当前 Unicode 处理的建议,请参阅 Unicode

SSL 连接

mysqlclient 和 PyMySQL DBAPI 接受在 “ssl” 键下的附加字典,可以使用 create_engine.connect_args 字典指定

engine = create_engine(
    "mysql+mysqldb://scott:tiger@192.168.0.134/test",
    connect_args={
        "ssl": {
            "ca": "/home/gord/client-ssl/ca.pem",
            "cert": "/home/gord/client-ssl/client-cert.pem",
            "key": "/home/gord/client-ssl/client-key.pem",
        }
    },
)

为方便起见,以下键也可以在 URL 中内联指定,它们将在其中自动解释为 “ssl” 字典:“ssl_ca”、“ssl_cert”、“ssl_key”、“ssl_capath”、“ssl_cipher”、“ssl_check_hostname”。示例如下

connection_uri = (
    "mysql+mysqldb://scott:tiger@192.168.0.134/test"
    "?ssl_ca=/home/gord/client-ssl/ca.pem"
    "&ssl_cert=/home/gord/client-ssl/client-cert.pem"
    "&ssl_key=/home/gord/client-ssl/client-key.pem"
)

将 MySQLdb 与 Google Cloud SQL 结合使用

Google Cloud SQL 现在建议使用 MySQLdb 方言。使用如下 URL 连接

mysql+mysqldb://root@/<dbname>?unix_socket=/cloudsql/<projectid>:<instancename>

服务器端游标

mysqldb 方言支持服务器端游标。请参阅 服务器端游标

PyMySQL

通过 PyMySQL 驱动程序支持 MySQL / MariaDB 数据库。

DBAPI

有关 PyMySQL 的文档和下载信息(如果适用)可在以下网址获取:https://py.mysqlserver.cn/

连接

连接字符串

mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]

Unicode

有关当前 Unicode 处理的建议,请参阅 Unicode

SSL 连接

PyMySQL DBAPI 接受与 MySQLdb 相同的 SSL 参数,如 SSL 连接 中所述。有关其他示例,请参阅该部分。

如果服务器使用自动生成的自签名证书或与主机名不匹配的证书(从客户端的角度来看),则可能还需要在 PyMySQL 中指示 ssl_check_hostname=false

connection_uri = (
    "mysql+pymysql://scott:tiger@192.168.0.134/test"
    "?ssl_ca=/home/gord/client-ssl/ca.pem"
    "&ssl_cert=/home/gord/client-ssl/client-cert.pem"
    "&ssl_key=/home/gord/client-ssl/client-key.pem"
    "&ssl_check_hostname=false"
)

MySQL-Python 兼容性

pymysql DBAPI 是 MySQL-python (MySQLdb) 驱动程序的纯 Python 端口,目标是 100% 兼容。MySQL-python 的大多数行为说明也适用于 pymysql 驱动程序。

MariaDB-Connector

通过 MariaDB Connector/Python 驱动程序支持 MySQL / MariaDB 数据库。

DBAPI

有关 MariaDB Connector/Python 的文档和下载信息(如果适用)可在以下网址获取:https://pypi.ac.cn/project/mariadb/

连接

连接字符串

mariadb+mariadbconnector://<user>:<password>@<host>[:<port>]/<dbname>

驱动程序状态

MariaDB Connector/Python 使 Python 程序能够使用符合 Python DB API 2.0 (PEP-249) 的 API 访问 MariaDB 和 MySQL 数据库。它用 C 语言编写,并使用 MariaDB Connector/C 客户端库进行客户端服务器通信。

请注意,mariadb:// 连接 URI 的默认驱动程序仍然是 mysqldbmariadb+mariadbconnector:// 是使用此驱动程序所必需的。

MySQL-Connector

通过 MySQL Connector/Python 驱动程序支持 MySQL / MariaDB 数据库。

DBAPI

有关 MySQL Connector/Python 的文档和下载信息(如果适用)可在以下网址获取:https://pypi.ac.cn/project/mysql-connector-python/

连接

连接字符串

mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname>

注意

MySQL Connector/Python DBAPI 自发布以来存在许多问题,其中一些问题可能仍未解决,并且 mysqlconnector 方言**未作为 SQLAlchemy 持续集成的一部分进行测试**。推荐的 MySQL 方言是 mysqlclient 和 PyMySQL。

asyncmy

通过 asyncmy 驱动程序支持 MySQL / MariaDB 数据库。

DBAPI

有关 asyncmy 的文档和下载信息(如果适用)可在以下网址获取:https://github.com/long2ice/asyncmy

连接

连接字符串

mysql+asyncmy://user:password@host:port/dbname[?key=value&key=value...]

使用特殊的 asyncio 调解层,asyncmy 方言可用作 SQLAlchemy asyncio 扩展包的后端。

此方言通常应仅与 create_async_engine() 引擎创建函数一起使用

from sqlalchemy.ext.asyncio import create_async_engine

engine = create_async_engine(
    "mysql+asyncmy://user:pass@hostname/dbname?charset=utf8mb4"
)

aiomysql

通过 aiomysql 驱动程序支持 MySQL / MariaDB 数据库。

DBAPI

有关 aiomysql 的文档和下载信息(如果适用)可在以下网址获取:https://github.com/aio-libs/aiomysql

连接

连接字符串

mysql+aiomysql://user:password@host:port/dbname[?key=value&key=value...]

aiomysql 方言是 SQLAlchemy 的第二个 Python asyncio 方言。

使用特殊的 asyncio 调解层,aiomysql 方言可用作 SQLAlchemy asyncio 扩展包的后端。

此方言通常应仅与 create_async_engine() 引擎创建函数一起使用

from sqlalchemy.ext.asyncio import create_async_engine

engine = create_async_engine(
    "mysql+aiomysql://user:pass@hostname/dbname?charset=utf8mb4"
)

cymysql

通过 CyMySQL 驱动程序支持 MySQL / MariaDB 数据库。

DBAPI

有关 CyMySQL 的文档和下载信息(如果适用)可在以下网址获取:https://github.com/nakagami/CyMySQL

连接

连接字符串

mysql+cymysql://<username>:<password>@<host>/<dbname>[?<options>]

注意

CyMySQL 方言**未作为 SQLAlchemy 持续集成的一部分进行测试**,并且可能存在未解决的问题。推荐的 MySQL 方言是 mysqlclient 和 PyMySQL。

pyodbc

通过 PyODBC 驱动程序支持 MySQL / MariaDB 数据库。

DBAPI

有关 PyODBC 的文档和下载信息(如果适用)可在以下网址获取:https://pypi.ac.cn/project/pyodbc/

连接

连接字符串

mysql+pyodbc://<username>:<password>@<dsnname>

注意

MySQL 的 PyODBC 方言**未作为 SQLAlchemy 持续集成的一部分进行测试**。推荐的 MySQL 方言是 mysqlclient 和 PyMySQL。但是,如果您想使用 mysql+pyodbc 方言并需要完全支持 utf8mb4 字符(包括表情符号等补充字符),请务必使用最新版本的 MySQL Connector/ODBC,并在您的 DSN 或连接字符串中指定 “ANSI” (**不是** “Unicode”)版本的驱动程序。

传递精确的 pyodbc 连接字符串

import urllib

connection_string = (
    "DRIVER=MySQL ODBC 8.0 ANSI Driver;"
    "SERVER=localhost;"
    "PORT=3307;"
    "DATABASE=mydb;"
    "UID=root;"
    "PWD=(whatever);"
    "charset=utf8mb4;"
)
params = urllib.parse.quote_plus(connection_string)
connection_uri = "mysql+pyodbc:///?odbc_connect=%s" % params