SqlAlchemy 2.0 中文文档(四十九)(4)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: SqlAlchemy 2.0 中文文档(四十九)

SqlAlchemy 2.0 中文文档(四十九)(3)https://developer.aliyun.com/article/1563029


MySQL / MariaDB 特定的索引选项

可用的 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 通过 Indexmysql_prefix 参数提供了这个功能:

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

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

另请参阅

创建索引 - MySQL 文档

索引类型

一些 MySQL 存储引擎允许在创建索引或主键约束时指定索引类型。SQLAlchemy 通过 Indexmysql_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 存储引擎的有效索引类型。

更多信息请参阅:

dev.mysql.com/doc/refman/5.0/en/create-index.html

dev.mysql.com/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 都提供了创建带有一定长度的索引条目的选项,其中“长度”指的是将成为索引一部分的每个值中的字符或字节数。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 通过 Indexmysql_prefix 参数提供了这个功能:

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

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

另请参阅

创建索引 - 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 存储引擎的有效索引类型。

更多信息请参见:

dev.mysql.com/doc/refman/5.0/en/create-index.html

dev.mysql.com/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”。在ForeignKeyConstraintForeignKey上使用deferrableinitially关键字参数将导致这些关键字在 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” 关键字实际上更加隐匿,且在与 MySQL 或 MariaDB 后端一起明确禁止。此参数被 MySQL / MariaDB  默默忽略,但此外还导致 ON UPDATE 和 ON DELETE 选项也被后端忽略。因此,永远不应该在 MySQL / MariaDB  后端使用 MATCH;与 DEFERRABLE 和 INITIALLY 一样,可以使用自定义编译规则在 DDL 定义时纠正  ForeignKeyConstraint。

外键约束的反射

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

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

另请参阅

创建表格参数,包括存储引擎

需要避免的外键参数

MySQL 和 MariaDB 都不支持外键参数“DEFERRABLE”、“INITIALLY”或“MATCH”。在 ForeignKeyConstraintForeignKey 中使用 deferrableinitially 关键字参数会使这些关键字在 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” 关键字实际上更加阴险,并且在与 MySQL 或 MariaDB 后端一起使用时,SQLAlchemy  明确禁止使用此参数。这个参数被 MySQL / MariaDB 默默地忽略,但此外,还会导致后端也忽略 ON UPDATE 和 ON  DELETE 选项。因此,不应该在 MySQL / MariaDB 后端使用 MATCH;与 DEFERRABLE 和 INITIALLY  一样,可以使用自定义编译规则来在 DDL 定义时纠正 ForeignKeyConstraint。

外键约束的反射

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

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

另请参阅

包括存储引擎的 CREATE TABLE 参数

MySQL / MariaDB 唯一约束和反射

SQLAlchemy 支持带有标志 unique=TrueIndex 构造,表示唯一索引,以及表示唯一约束的 UniqueConstraint 构造。当发出 DDL 以创建这些约束时,MySQL / MariaDB 支持这两种对象/语法。然而,MySQL / MariaDB  没有与唯一索引分离的唯一约束构造;也就是说,在 MySQL / MariaDB 上,“UNIQUE” 约束等效于创建一个 “UNIQUE  INDEX”。

当反射这些结构时,Inspector.get_indexes()Inspector.get_unique_constraints() 方法都会在 MySQL / MariaDB 中为唯一索引返回一个条目。然而,当使用 Table(..., autoload_with=engine) 进行完整表反射时,UniqueConstraint 结构在任何情况下都不是完全反映的 Table 结构的一部分;这个结构总是由在 Table.indexes 集合中存在 unique=True 设置的 Index 表示。

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,这与所有其他数据类型的行为相反:
```py
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 的 explicit_defaults_for_timestamp 配置标志在 MySQL 端更改此 MySQL  的行为,该标志在 MySQL 5.6 中引入。启用此服务器设置后,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 / MariaDB 的 explicit_defaults_for_timestamp 渲染 ON UPDATE CURRENT TIMESTAMP
MySQL / MariaDB 历史上扩展了 DDL,将`TIMESTAMP`数据类型扩展为“TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP”,其中包含非标准的 SQL,当发生 UPDATE 时自动更新列为当前时间戳,从而消除了在需要服务器端更新更改的情况下使用触发器的常规需求。
MySQL 5.6 引入了一个新标志[explicit_defaults_for_timestamp](https://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_explicit_defaults_for_timestamp),禁用了上述行为,在 MySQL 8 中,此标志默认为 true,这意味着为了获得 MySQL 的“on update timestamp”而不更改此标志,必须显式呈现上述 DDL。此外,对于 DATETIME 数据类型,相同的 DDL 也是有效的。
SQLAlchemy 的 MySQL 方言目前还没有选项来生成 MySQL 的“ON UPDATE CURRENT_TIMESTAMP”子句,需要注意的是这不是一个通用的“ON UPDATE”,因为标准 SQL 中没有这样的语法。SQLAlchemy 的`Column.server_onupdate`参数目前与这种特殊的 MySQL 行为无关。
要生成这个 DDL,请使用`Column.server_default`参数,并传递一个包含 ON UPDATE 子句的文本子句:
```py
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 端使用 MySQL 5.6 引入的explicit_defaults_for_timestamp配置标志来更改。启用此服务器设置后,TIMESTAMP 列在 MySQL 端的默认值和可空性方面的行为与任何其他数据类型相同。

然而,为了适应大多数不指定此新标志的 MySQL 数据库,SQLAlchemy 对于不指定 nullable=False 的任何 TIMESTAMP 列都显式地发出“NULL”指定符。为了适应指定了 nullable=False 的 TIMESTAMP 列的新数据库,SQLAlchemy 还为这些列发出 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 – 布尔值,将“布尔模式”设置为真
  • in_natural_language_mode – 布尔值,将“自然语言”设置为真
  • with_query_expansion – 布尔值,将“查询扩展”设置为真

版本 1.4.19 中新增。

另请参阅

ColumnElement.match()

成员

in_boolean_mode(), in_natural_language_mode(), inherit_cache, with_query_expansion()

类签名

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

method in_boolean_mode() → Self

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

返回:

带有修改的新 match 实例。

method in_natural_language_mode() → Self

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

返回:

带有修改的新 match 实例。

attribute inherit_cache: bool | None = True

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

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

如果 SQL 与对象对应的类没有基于该类本地属性而不是其超类发生变化,则可以将此标志设置为 True

另请参阅

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

method with_query_expansion() → Self

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

返回:

应用了修改的 match 实例。


SqlAlchemy 2.0 中文文档(四十九)(5)https://developer.aliyun.com/article/1563031

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
5月前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(二十九)(3)
SqlAlchemy 2.0 中文文档(二十九)
50 4
|
5月前
|
存储 Java 测试技术
SqlAlchemy 2.0 中文文档(七十三)(3)
SqlAlchemy 2.0 中文文档(七十三)
40 8
|
5月前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(二十九)(2)
SqlAlchemy 2.0 中文文档(二十九)
48 7
|
5月前
|
SQL 关系型数据库 测试技术
SqlAlchemy 2.0 中文文档(七十三)(2)
SqlAlchemy 2.0 中文文档(七十三)
55 4
|
5月前
|
SQL 存储 关系型数据库
SqlAlchemy 2.0 中文文档(二十九)(1)
SqlAlchemy 2.0 中文文档(二十九)
54 4
|
5月前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(七十三)(4)
SqlAlchemy 2.0 中文文档(七十三)
51 2
|
5月前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(二十九)(4)
SqlAlchemy 2.0 中文文档(二十九)
56 4
|
5月前
|
SQL 关系型数据库 测试技术
SqlAlchemy 2.0 中文文档(七十三)(1)
SqlAlchemy 2.0 中文文档(七十三)
49 1
|
5月前
|
SQL JSON 关系型数据库
SqlAlchemy 2.0 中文文档(七十三)(5)
SqlAlchemy 2.0 中文文档(七十三)
55 1
|
5月前
|
SQL 缓存 数据库连接
SqlAlchemy 2.0 中文文档(二十二)(2)
SqlAlchemy 2.0 中文文档(二十二)
63 3