MySQL 和 MariaDB


支持 MySQL / MariaDB 数据库。


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


支持的 MySQL / MariaDB 版本


支撑类型


版本


支持的版本

5.6+ / 10+


尽力而为

5.0.2+ / 5.0.2+


DBAPI 支持


以下 dialect/DBAPI 选项可用。有关连接信息,请参阅各个 DBAPI 部分。


支持的版本和功能


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


在 1.4 版本发生变更: 现在支持的最低 MySQL 版本为 5.0.2。


MariaDB 支持


MySQL 的 MariaDB 变体保留了与 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” 选项可以同时用于使用带有 “mysql” 和 “mariadb” 方言的 URL 的应用程序:

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 版本中的新功能: 添加了 “mariadb” 方言名称,支持 MySQL 方言的 “MariaDB-only mode”。


连接超时和断开连接


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

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


要对池连接进行更全面的断开连接检测,包括适应服务器重启和网络问题,可以采用预 ping 方法。有关当前方法,请参阅 Dealing with Disconnects


另请参阅


处理断开连接 - 有关处理超时连接和数据库重启的几种技术的背景知识。


包含存储引擎的 CREATE TABLE 参数


MySQL 和 MariaDB 的 CREATE TABLE 语法都包含大量特殊选项,包括 ENGINE、CHARSETMAX_ROWSROW_FORMATINSERT_METHOD,以及更多。 要适应这些参数的呈现,请指定 mysql_argument_name=“value” 的 例如,要指定一个带有 InnoDBENGINEutf8mb4CHARSETKEY_BLOCK_SIZE1024 个:

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


当支持 MariaDB-Only Mode 模式时,还必须包含针对 “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 KEYWORD_NAMECREATE TABLE 语句。这些名称中的少数名称将使用空格而不是下划线呈现;为了支持这一点,MySQL 方言可以识别这些特定名称,其中包括 DATA DIRECTORY (例如 mysql_data_directory)、字符(例如 mysql_character_set)和 INDEX DIRECTORY(例如 mysql_index_directory)。


最常见的参数是 mysql_engine,它指的是 table 的存储引擎。从历史上看, MySQL 服务器安装将默认为 MyISAM 对于此值,尽管较新的版本可能默认为 InnoDBInnoDB 引擎通常是首选,因为它支持事务和外键。


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


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


区分大小写和表反射


MySQL 和 MariaDB 对区分大小写的标识符名称的支持不一致,其支持基于底层作系统的特定细节。但是,据观察,无论存在何种区分大小写的行为,外键声明中的表名称始终以全小写形式从数据库接收,因此无法准确反映相互关联的表使用混合大小写标识符名称的架构。


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


事务隔离级别


所有 MySQL / MariaDB dialect 都支持通过特定于 dialect 的参数 create_engine.isolation_level 设置事务隔离级别 接受 by create_engine() 以及 Connection.execution_options.isolation_level 参数传递给 Connection.execution_options() 。此功能通过为每个新连接发出命令 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 的有效值包括:


  • 读取已提交


  • 读取 UNCOMMITTED


  • 可重复读取


  • 序列 化


  • 自动提交


特殊的 AUTOCOMMIT 值利用了各种 “autocommit” 属性,目前由 MySQLdb、MySQL-Client、MySQL-Connector Python 和 PyMySQL。 使用它, 数据库连接将为 选择 @@autocommit;


隔离级别配置还有更多选项,例如链接到主引擎的“子引擎”对象,每个选项都适用 不同的隔离级别设置。 请参阅讨论 设置事务隔离级别,包括 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 参数。此标志还可用于在某些存储引擎的多列键中的辅助列上启用自动递增:

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 版后已移除: 已弃用 dialect 级别 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 编码仅支持最多 3 个字节的码位,而不是 4 个字节。因此,当与包含大于三个字节的代码点的 MySQL 或 MariaDB 数据库通信时,如果数据库和客户端 DBAPI 都支持,则首选此新字符集,如下所示:

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


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


为了对使用旧版创建的架构使用 utf8mb4 编码 utf8 时,可能需要更改 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"
)


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


SQLAlchemy 本身无法可靠地呈现此 _binary 前缀,因为它不适用于 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” 事件将调用 “SET” 语句时,特定 DBAPI 连接为 首先为给定池创建,然后连接才可用于 连接池。 此外,由于该函数是使用 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 扩展提供一些有限的直接支持。


插入/删除...返回


MariaDB 方言支持 10.5+ 的 INSERT..RETURNING删除。。RETURNING (10.0+) 语法。插入。。但是,在某些情况下,可以自动使用 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 的支持


插入。。。ON DUPLICATE KEY UPDATE (Upsert) (更新插入))¶


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


SQLAlchemy 通过特定于 MySQL 的 insert() 函数,该函数提供生成方法 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 用于执行已 existing row, 使用新值和值的任意组合 从提议的插入。 这些值通常使用 关键字参数传递给 Insert.on_duplicate_key_update() 给定的列键值(通常是列的名称,除非它 指定 Column.key ) 作为键和文本或 SQL 表达式 as 值:

>>> 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 语句。与更新 对象 不需要特殊标志来指定 intent,因为参数形式是 此上下文是明确的:

>>> 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 中的参数排序 UPDATE 子句


警告


Insert.on_duplicate_key_update() 方法考虑 Python 端的默认 UPDATE 值或生成函数,例如使用 Column.onupdate 指定的值。除非在参数中显式指定这些值,否则不会对 ON DUPLICATE KEY 样式执行这些值。


为了引用建议的插入行,特殊别名 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>) 的 VALUES(%)


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


rowcount 支持


SQLAlchemy 将 DBAPI cursor.rowcount 属性标准化为“UPDATE 或 DELETE 匹配的行数”语句的通常定义。这与大多数 MySQL DBAPI 驱动程序上的默认设置相矛盾,即“实际修改/删除的行数”。因此,SQLAlchemy MySQL 方言总是添加常量。客户。FOUND_ROWS flag 或目标方言的等效项。 此设置当前是硬编码的。


另请参阅

CursorResult.rowcount


MySQL / MariaDB 特定索引选项


Index 结构的 MySQL 和 MariaDB 特定扩展可用。


索引长度


MySQL 和 MariaDB 都提供了创建具有一定长度的索引条目的选项,其中 “length” 是指每个值中的字符数或字节数,它将 成为索引的一部分。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}
)


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


索引前缀


MySQL 存储引擎允许您在创建 一个索引。SQLAlchemy 通过 mysql_prefix Index 上的参数:

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


传递给 keyword 参数的值将简单地传递给底层 CREATE INDEX,因此它必须是 MySQL 存储引擎的有效索引前缀。


另请参阅


CREATE INDEX - MySQL 文档


索引类型


某些 MySQL 存储引擎允许您在创建 索引或主键约束。SQLAlchemy 通过 mysql_using Index 上的参数:

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.mysql.com/doc/refman/5.0/en/create-index.html

https://dev.mysql.com/doc/refman/5.0/en/create-table.html


索引解析器


MySQL 中的 CREATE FULLTEXT INDEX 还支持“WITH PARSER”选项。这可以通过 keyword 参数 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 后端被忽略,请使用自定义编译规则:

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 存储引擎时,表 reflection 将不包含外键。 对于这些表,您可以提供 ForeignKeyConstraint 的 ForeignKeyConstraint 中:

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


MySQL / MariaDB 唯一约束和反射


SQLAlchemy 支持带有标志 unique=True(表示 UNIQUE 索引)的 Index 结构,以及 UniqueConstraint 结构,表示 UNIQUE 约束。在发出 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 问题


渲染 ON UPDATE CURRENT TIMESTAMP for MySQL / MariaDB 的 explicit_defaults_for_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,即使我们没有指定它。


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


但是,为了适应绝大多数未指定此新标志的 MySQL 数据库,SQLAlchemy 会使用任何未指定 nullable=False 的 TIMESTAMP 列显式发出“NULL”说明符。为了容纳指定 explicit_defaults_for_timestamp 、 SQLAlchemy 还为指定 nullable=False 的 False 值。以下示例说明:

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 (X, Y) AGAINST ('TEXT') 子句。


sqlalchemy.dialects.mysql 中。匹配


生成 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() 函数是 ColumnElement.match() 方法在所有 SQL 表达式上都可用,就像使用 ColumnElement.match() 时一样,但允许传递多个列


参数

  • cols – 要匹配的列表达式


  • st —— 要比较的表达式


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


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


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


在 1.4.19 版本加入.


类签名


sqlalchemy.dialects.mysql.match sqlalchemy.sql.expression.Generative sqlalchemy.sql.expression.BinaryExpression


方法 sqlalchemy.dialects.mysql.match. in_boolean_mode Self


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


结果


应用了修改的新 match 实例。


方法 sqlalchemy.dialects.mysql.match. in_natural_language_mode Self


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


结果


应用了修改的新 match 实例。


属性 sqlalchemy.dialects.mysql.match. inherit_cache:boolNone = True


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


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


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


另请参阅


启用对自定义构造的缓存支持 - 设置 HasCacheKey.inherit_cache 第三方或用户定义的 SQL 构造的属性。


方法 sqlalchemy.dialects.mysql.match. with_query_expansion Self


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


结果


应用了修改的新 match 实例。


MySQL 数据类型


与所有 SQLAlchemy 方言一样,所有已知对 MySQL 有效的 UPPERCASE 类型都可以从顶级方言导入:

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 年的单字节存储。


sqlalchemy.dialects.mysql 中。BIGINT 的¶


MySQL BIGINTEGER 类型。


类签名


sqlalchemy.dialects.mysql.BIGINT sqlalchemy.dialects.mysql.types._IntegerTypesqlalchemy.types.BIGINT


方法 sqlalchemy.dialects.mysql.BIGINT. __init__display_width=None**kw


构造一个 BIGINTEGER。


参数

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


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


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


sqlalchemy.dialects.mysql 中。二元的


SQL BINARY 类型。


类签名


sqlalchemy.dialects.mysql.BINARYsqlalchemy.types._Binary


sqlalchemy.dialects.mysql 中。位元


MySQL BIT 类型。


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


方法 sqlalchemy.dialects.mysql.BIT. __init__length=None)¶


构造一个 BIT。


参数


length – 可选,位数。


sqlalchemy.dialects.mysql 中。斑点


SQL BLOB 类型。


类签名


sqlalchemy.dialects.mysql.BLOBsqlalchemy.types.LargeBinary


方法 sqlalchemy.dialects.mysql.BLOB. __init__length:intNone=None


继承自 sqlalchemy.types.LargeBinary.__init__ LargeBinary 的方法


构造 LargeBinary 类型。


参数


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


sqlalchemy.dialects.mysql 中。布尔


SQL BOOLEAN 类型。


类签名


sqlalchemy.dialects.mysql.BOOLEANsqlalchemy.types.Boolean


方法 sqlalchemy.dialects.mysql.BOOLEAN. __init__create_constraint: bool = False, name:strNone=None, _create_events: bool = True, _adapted_from:SchemaTypeNone=None


继承自 sqlalchemy.types.Boolean.__init__ Boolean 的方法


构造一个布尔值。


参数
  • create_constraint


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


    注意


    强烈建议将 CHECK 约束 具有显式名称,以便支持 Schema-Management 关注。 这可以通过设置 Boolean.name 参数中,或者通过设置 适当的命名约定;看 为背景配置 Constraint Naming Conventions


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


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


sqlalchemy.dialects.mysql 中。字符


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


类签名


sqlalchemy.dialects.mysql.CHAR sqlalchemy.dialects.mysql.types._StringTypesqlalchemy.types.CHAR


方法 sqlalchemy.dialects.mysql.CHAR. __init__length=None**kwargs


构造一个 CHAR。


参数

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


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


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


sqlalchemy.dialects.mysql 中。日期


SQL DATE 类型。


类签名


sqlalchemy.dialects.mysql.DATEsqlalchemy.types.Date


sqlalchemy.dialects.mysql 中。日期时间


MySQL DATETIME 类型。


方法 sqlalchemy.dialects.mysql.DATETIME. __init__timezone=Falsefsp=None


构造 MySQL DATETIME 类型。


参数

  • timezone—— MySQL 方言不使用。


  • FSP


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


    注意


    DBAPI 驱动程序对秒的小数部分的支持可能会受到限制;当前支持包括 MySQL Connector/Python。


sqlalchemy.dialects.mysql 中。十进制


MySQL DECIMAL 类型。


类签名


sqlalchemy.dialects.mysql.DECIMAL sqlalchemy.dialects.mysql.types._NumericTypesqlalchemy.types.DECIMAL


方法 sqlalchemy.dialects.mysql.DECIMAL. __init__precision=Nonescale=Noneasdecimal=True**kw


构造一个 DECIMAL。


参数

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


  • scale- 小数点后的位数。


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


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


sqlalchemy.dialects.mysql 中。


MySQL DOUBLE 类型。


类签名


sqlalchemy.dialects.mysql.DOUBLEsqlalchemy.dialects.mysql.types._FloatTypesqlalchemy.types.DOUBLE


方法 sqlalchemy.dialects.mysql.DOUBLE. __init__precision=Nonescale=Noneasdecimal=True**kw


构造一个 DOUBLE。


注意


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


参数

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


  • scale- 小数点后的位数。


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


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


sqlalchemy.dialects.mysql 中。枚举


MySQL ENUM 类型。


类签名


sqlalchemy.dialects.mysql.ENUM sqlalchemy.types.NativeForEmulatedsqlalchemy.types.Enumsqlalchemy.dialects.mysql.types._StringType


方法 sqlalchemy.dialects.mysql.ENUM. __init__*enums**kw


构造 ENUM。


例如:

Column("myenum", ENUM("foo", "bar", "baz"))

参数

  • 枚举


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


  • 严格


    此标志无效。


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


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


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


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


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


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


sqlalchemy.dialects.mysql 中。浮点数(FLOAT)


MySQL FLOAT 类型。


类签名


sqlalchemy.dialects.mysql.FLOAT sqlalchemy.dialects.mysql.types._FloatTypesqlalchemy.types.FLOAT


方法 sqlalchemy.dialects.mysql.FLOAT. __init__precision=Nonescale=Noneasdecimal=False**kw


构造一个 FLOAT。


参数

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


  • scale- 小数点后的位数。


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


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


sqlalchemy.dialects.mysql 中。INET4


MariaDB 的 INET4 列类型


2.0.37 新版功能.


sqlalchemy.dialects.mysql 中。INET6 的¶


MariaDB 的 INET6 列类型


2.0.37 新版功能.


sqlalchemy.dialects.mysql 中。整数


MySQL INTEGER 类型。


类签名


sqlalchemy.dialects.mysql.INTEGER sqlalchemy.dialects.mysql.types._IntegerTypesqlalchemy.types.INTEGER


方法 sqlalchemy.dialects.mysql.INTEGER. __init__display_width=None**kw


构造一个 INTEGER。


参数

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


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


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


sqlalchemy.dialects.mysql 中。JSON格式¶


MySQL JSON 类型。


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


每当 base JSON 数据类型用于 MySQL 或 MariaDB 后端。


另请参阅


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


JSON 类型支持 JSON 值的持久化以及 JSON 提供的核心索引作 datatype 来渲染 JSON_EXTRACT 函数。


sqlalchemy.dialects.mysql 中。LONGBLOB


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


类签名


sqlalchemy.dialects.mysql.LONGBLOB sqlalchemy.types._Binary


sqlalchemy.dialects.mysql 中。长文本


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


类签名


sqlalchemy.dialects.mysql.LONGTEXT sqlalchemy.dialects.mysql.types._StringType


方法 sqlalchemy.dialects.mysql.LONGTEXT. __init__**kwargs


构造一个 LONGTEXT。


参数

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


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


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


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


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


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


sqlalchemy.dialects.mysql 中。MEDIUMBLOB


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


类签名


sqlalchemy.dialects.mysql.MEDIUMBLOB sqlalchemy.types._Binary


sqlalchemy.dialects.mysql 中。MEDIUMINT 的函数¶


MySQL MEDIUMINTEGER 类型。


类签名


sqlalchemy.dialects.mysql.MEDIUMINT sqlalchemy.dialects.mysql.types._IntegerType


方法 sqlalchemy.dialects.mysql.MEDIUMINT. __init__display_width=None**kw


构造一个 MEDIUMINTEGER


参数

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


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


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


sqlalchemy.dialects.mysql 中。MEDIUMTEXT


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


类签名


sqlalchemy.dialects.mysql.MEDIUMTEXT sqlalchemy.dialects.mysql.types._StringType


方法 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。这不会影响存储的数据类型,只影响字符数据的排序。


sqlalchemy.dialects.mysql 中。NCHAR的¶


MySQL NCHAR 类型。


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


类签名


sqlalchemy.dialects.mysql.NCHAR sqlalchemy.dialects.mysql.types._StringTypesqlalchemy.types.NCHAR


方法 sqlalchemy.dialects.mysql.NCHAR. __init__length=None**kwargs


构造一个 NCHAR.


参数

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


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


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


sqlalchemy.dialects.mysql 中。数值


MySQL NUMERIC 类型。


类签名


sqlalchemy.dialects.mysql.NUMERIC sqlalchemy.dialects.mysql.types._NumericTypesqlalchemy.types.NUMERIC


方法 sqlalchemy.dialects.mysql.NUMERIC. __init__precision=Nonescale=Noneasdecimal=True**kw


构造一个 NUMERIC。


参数

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


  • scale- 小数点后的位数。


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


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


sqlalchemy.dialects.mysql 中。NVARCHAR的¶


MySQL NVARCHAR 类型。


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


类签名


sqlalchemy.dialects.mysql.NVARCHAR sqlalchemy.dialects.mysql.types._StringTypesqlalchemy.types.NVARCHAR


方法 sqlalchemy.dialects.mysql.NVARCHAR. __init__length=None**kwargs


构造一个 NVARCHAR。


参数

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


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


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


sqlalchemy.dialects.mysql 中。真实


MySQL REAL 类型。


类签名


sqlalchemy.dialects.mysql.REAL sqlalchemy.dialects.mysql.types._FloatTypesqlalchemy.types.REAL


方法 sqlalchemy.dialects.mysql.REAL. __init__precision=Nonescale=Noneasdecimal=True**kw


构造一个 REAL.


注意


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


参数

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


  • scale- 小数点后的位数。


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


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


sqlalchemy.dialects.mysql 中。SET组¶


MySQL SET 类型。


类签名


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


方法 sqlalchemy.dialects.mysql.SET. __init__*values**kw


构造一个 SET。


例如:

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


如果 this set 将用于生成表的 DDL,或者如果 SET.retrieve_as_bitwise 标志设置为 True。


参数

  • values— 此 SET 的有效值范围。这些值不会被引用,在生成架构时,它们将被转义并用单引号括起来。


  • convert_unicode – 与 String.convert_unicode


  • collation —— 与 String.collation 相同


  • charset —— 与 VARCHAR.charset 相同。


  • ascii —— 与 VARCHAR.ascii 相同。


  • unicode – 与 VARCHAR.unicode 相同。


  • binary —— 与 VARCHAR.binary 相同。

  • retrieve_as_bitwise


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


    警告


    使用 SET.retrieve_as_bitwise 时,它是 必须将设置值列表表示为 与 MySQL 数据库上存在的顺序完全相同


sqlalchemy.dialects.mysql 中。SMALLINT


MySQL SMALLINTEGER 类型。


类签名


sqlalchemy.dialects.mysql.SMALLINT sqlalchemy.dialects.mysql.types._IntegerTypesqlalchemy.types.SMALLINT


方法 sqlalchemy.dialects.mysql.SMALLINT. __init__display_width=None**kw


构造一个 SMALLINTEGER。


参数

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


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


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


sqlalchemy.dialects.mysql 中。发短信


MySQL TEXT 类型,用于编码高达 2^16 字节的字符存储。


类签名


sqlalchemy.dialects.mysql.TEXTsqlalchemy.dialects.mysql.types._StringTypesqlalchemy.types.TEXT)


方法 sqlalchemy.dialects.mysql.TEXT. __init__length=None**kw


构造一个 TEXT。


参数

  • length– 可选,如果提供,服务器可以优化存储 通过替换足以存储 length 字节数。


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


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


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


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


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


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


sqlalchemy.dialects.mysql 中。时间


MySQL TIME 类型。


方法 sqlalchemy.dialects.mysql.TIME. __init__timezone=Falsefsp=None


构造 MySQL TIME 类型。


参数

  • timezone—— MySQL 方言不使用。


  • FSP


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


    注意


    DBAPI 驱动程序对秒的小数部分的支持可能会受到限制;当前支持包括 MySQL Connector/Python。


sqlalchemy.dialects.mysql 中。时间戳


MySQL TIMESTAMP 类型。


方法 sqlalchemy.dialects.mysql.TIMESTAMP. __init__timezone=Falsefsp=None


构造 MySQL TIMESTAMP 类型。


参数

  • timezone—— MySQL 方言不使用。


  • FSP


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


    注意


    DBAPI 驱动程序对秒的小数部分的支持可能会受到限制;当前支持包括 MySQL Connector/Python。


sqlalchemy.dialects.mysql 中。TINYBLOB


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


类签名


sqlalchemy.dialects.mysql.TINYBLOB sqlalchemy.types._Binary


sqlalchemy.dialects.mysql 中。TINYINT的¶


MySQL TINYINT 类型。


类签名


sqlalchemy.dialects.mysql.TINYINT sqlalchemy.dialects.mysql.types._IntegerType


方法 sqlalchemy.dialects.mysql.TINYINT. __init__display_width=None**kw


构造一个 TINYINT。


参数

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


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


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


sqlalchemy.dialects.mysql 中。TINYTEXT (英语) ¶


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


类签名


sqlalchemy.dialects.mysql.TINYTEXT sqlalchemy.dialects.mysql.types._StringType


方法 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。这不会影响存储的数据类型,只影响字符数据的排序。


sqlalchemy.dialects.mysql 中。VARBINARY


SQL VARBINARY 类型。


类签名


sqlalchemy.dialects.mysql.VARBINARYsqlalchemy.types._Binary


sqlalchemy.dialects.mysql 中。VARCHAR 函数¶


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


类签名


sqlalchemy.dialects.mysql.VARCHAR sqlalchemy.dialects.mysql.types._StringTypesqlalchemy.types.VARCHAR


方法 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。这不会影响存储的数据类型,只影响字符数据的排序。


sqlalchemy.dialects.mysql 中。年份


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


MySQL DML 结构


对象名称

描述


insert(表)


构造特定于 MySQL/MariaDB 的变体 Insert 构建。


插入


特定于 MySQL 的 INSERT 实现。


函数 sqlalchemy.dialects.mysql。inserttable _DMLTableArgument 插入


构造特定于 MySQL/MariaDB 的变体 Insert 构建。


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


Insert 构造包括其他方法 Insert.on_duplicate_key_update()


sqlalchemy.dialects.mysql 中。插入


特定于 MySQL 的 INSERT 实现。


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


Insert 对象是使用 sqlalchemy.dialects.mysql.insert() 功能。


在 1.2 版本加入.


属性 sqlalchemy.dialects.mysql.Insert. inherit_cache:boolNone = False


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


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


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


另请参阅


启用对自定义构造的缓存支持 - 设置 HasCacheKey.inherit_cache 第三方或用户定义的 SQL 构造的属性。


attribute inserted插入属性 sqlalchemy.dialects.mysql.Insert. )¶


为 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”] 中。 请参阅 docsstring 的 ColumnCollection 获取更多示例。


另请参阅


插入。。。ON DUPLICATE KEY UPDATE (Upsert) - 如何使用 Insert.inserted 的示例


方法 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 指定的值。除非在此处手动指定值,否则不会对 UPDATE 的 ON DUPLICATE KEY UPDATE 样式执行这些值。


参数

*args


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


传递单个字典等效于 keyword argument 形式:

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


传递 2 元组列表表示 UPDATE 子句中的参数分配应按发送顺序排序,其方式类似于 Update 中描述的方式 构造整体 在 Parameter Ordered Updates 中:

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


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


在 1.2 版本加入.


mysqlclient (MySQL-Python 的分支)


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


数据库接口


mysqlclient(维护的 MySQL-Python 分支)的文档和下载信息(如果适用)可从以下网址获得: https://pypi.org/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"
)


另请参阅


PyMySQL 方言中的 SSL 连接


将 MySQLdb 与 Google Cloud SQL 结合使用


Google Cloud SQL 现在建议使用 MySQLdb 方言。使用如下所示的 URL 进行连接:

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


服务器端游标


mysqldb dialect 支持服务器端游标。请参见服务器端游标


PyMySQL 的¶


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


数据库接口


PyMySQL 的文档和下载信息(如果适用)可从以下网址获得: https://pymysql.readthedocs.io/


连接


连接字符串:

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 连接器


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


数据库接口


MariaDB 连接器/Python 的文档和下载信息(如果适用)可在以下网址获得: https://pypi.org/project/mariadb/


连接


连接字符串:

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


驱动程序状态


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


请注意,mariadb:// 连接 URI 的默认驱动程序仍然是 mysqldb。需要 mariadb+mariadbconnector:// 才能使用此驱动程序。


MySQL 连接器


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


数据库接口


MySQL Connector/Python 的文档和下载信息(如果适用)可从以下网址获得: https://pypi.org/project/mysql-connector-python/


连接


连接字符串:

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


注意


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


异步我的


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


数据库接口


asyncmy 的文档和下载信息(如果适用)可在以下位置获得: https://github.com/long2ice/asyncmy


连接


连接字符串:

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


使用特殊的 asyncio 中介层,asyncmy dialect 可用作 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 数据库。


数据库接口


aiomysql 的文档和下载信息(如果适用)可在以下位置获得: https://github.com/aio-libs/aiomysql


连接


连接字符串:

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


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


使用特殊的 asyncio 中介层,aiomysql dialect 可用作 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 数据库。


数据库接口


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


连接


连接字符串:

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


注意


CyMySQL 方言未作为 SQLAlchemy 的连续 集成,并且可能存在未解决的问题。推荐的 MySQL 方言是 mysqlclient 和 PyMySQL。

pyodbc


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


数据库接口


PyODBC 的文档和下载信息(如果适用)可从以下位置获得: https://pypi.org/project/pyodbc/


连接


连接字符串:

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


注意


PyODBC for MySQL 方言未作为 SQLAlchemy 的持续集成。推荐的 MySQL 方言是 mysqlclient 和 PyMySQL。但是,如果您想使用 mysql+pyodbc 方言并需要完全支持 utf8mb4 字符(包括表情符号等补充字符),请确保使用最新版本的 MySQL 连接器/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