SqlAlchemy 2.0 中文文档(五十二)(5)

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介: SqlAlchemy 2.0 中文文档(五十二)

SqlAlchemy 2.0 中文文档(五十二)(4)https://developer.aliyun.com/article/1563143


使用非整数数值类型的 IDENTITY

SQL Server 还允许将IDENTITYNUMERIC列一起使用。要在 SQLAlchemy 中顺利实现此模式,列的主要数据类型应保持为Integer,但是可以使用TypeEngine.with_variant()指定部署到 SQL Server 数据库的底层实现类型为Numeric

from sqlalchemy import Column
from sqlalchemy import Integer
from sqlalchemy import Numeric
from sqlalchemy import String
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class TestTable(Base):
    __tablename__ = "test"
    id = Column(
        Integer().with_variant(Numeric(10, 0), "mssql"),
        primary_key=True,
        autoincrement=True,
    )
    name = Column(String)

在上面的示例中,Integer().with_variant()提供了清晰的使用信息,准确描述了代码的意图。autoincrement仅适用于Integer的一般限制是在元数据级别而不是在每个方言级别上建立的。

当使用上述模式时,从插入行返回的主键标识符,也就是将被分配给诸如上述TestTable的 ORM 对象的值,当使用 SQL Server 时将是Decimal()的实例,而不是intNumeric类型的数值返回类型可以通过将 False 传递给Numeric.asdecimal来更改为返回浮点数。要将上述Numeric(10, 0)的返回类型规范化为返回 Python 整数(在 Python 3 中也支持“long”整数值),请使用TypeDecorator如下所示:

from sqlalchemy import TypeDecorator
class NumericAsInteger(TypeDecorator):
  '''normalize floating point return values into ints'''
    impl = Numeric(10, 0, asdecimal=False)
    cache_ok = True
    def process_result_value(self, value, dialect):
        if value is not None:
            value = int(value)
        return value
class TestTable(Base):
    __tablename__ = "test"
    id = Column(
        Integer().with_variant(NumericAsInteger, "mssql"),
        primary_key=True,
        autoincrement=True,
    )
    name = Column(String)

插入行为

在 INSERT 时处理IDENTITY列涉及两种关键技术。最常见的是能够获取给定IDENTITY列的“最后插入的值”,这是 SQLAlchemy 在许多情况下隐式执行的过程,最重要的是在 ORM 中。

获取此值的过程有几种变体:

  • 在绝大多数情况下,RETURNING 与 SQL Server 上的 INSERT 语句一起使用,以获取新生成的主键值:
INSERT  INTO  t  (x)  OUTPUT  inserted.id  VALUES  (?)
  • 从 SQLAlchemy 2.0 开始,默认还使用“Insert  Many Values” Behavior for INSERT statements 功能来优化多行 INSERT 语句;对于 SQL  Server,该功能适用于 RETURNING 和非 RETURNING INSERT 语句。
    从版本 2.0.10  开始更改:由于行排序问题,SQLAlchemy 版本 2.0.9 暂时禁用了 SQL Server 的“Insert Many Values”  Behavior for INSERT statements 功能。从 2.0.10 开始,该功能重新启用,并针对工作单元对 RETURNING  的排序要求进行特殊处理。
  • 当 RETURNING 不可用或通过implicit_returning=False禁用时,将使用scope_identity()函数或@@identity变量;后端的行为各不相同:
  • 使用 PyODBC 时,短语; select scope_identity()将附加到 INSERT 语句的末尾;为了接收值,将获取第二个结果集。假设有一个表:
t = Table(
    't',
    metadata,
    Column('id', Integer, primary_key=True),
    Column('x', Integer),
    implicit_returning=False
)
  • 一个 INSERT 看起来像:
INSERT  INTO  t  (x)  VALUES  (?);  select  scope_identity()
  • 其他方言,如 pymssql,在 INSERT 语句后将调用SELECT scope_identity() AS lastrowid。如果将标志use_scope_identity=False传递给create_engine(),则将使用语句SELECT @@identity AS lastrowid

包含IDENTITY列的表将禁止引用显式标识列的 INSERT 语句。当 SQLAlchemy 方言检测到使用核心insert()构造(而不是纯字符串 SQL)创建的 INSERT 构造引用标识列时,在这种情况下,将在继续插入语句之前发出SET IDENTITY_INSERT ON,并在执行后继续发出SET IDENTITY_INSERT OFF。给出这个例子:

m = MetaData()
t = Table('t', m, Column('id', Integer, primary_key=True),
                Column('x', Integer))
m.create_all(engine)
with engine.begin() as conn:
    conn.execute(t.insert(), {'id': 1, 'x':1}, {'id':2, 'x':2})

上述列将使用 IDENTITY 创建,但我们发出的 INSERT 语句指定了显式值。在回显输出中,我们可以看到 SQLAlchemy 如何处理这个问题:

CREATE  TABLE  t  (
  id  INTEGER  NOT  NULL  IDENTITY(1,1),
  x  INTEGER  NULL,
  PRIMARY  KEY  (id)
)
COMMIT
SET  IDENTITY_INSERT  t  ON
INSERT  INTO  t  (id,  x)  VALUES  (?,  ?)
((1,  1),  (2,  2))
SET  IDENTITY_INSERT  t  OFF
COMMIT

这是一个适用于测试和批量插入场景的辅助用例。

SEQUENCE 支持

Sequence对象创建“真实”序列,即CREATE SEQUENCE

>>> from sqlalchemy import Sequence
>>> from sqlalchemy.schema import CreateSequence
>>> from sqlalchemy.dialects import mssql
>>> print(CreateSequence(Sequence("my_seq", start=1)).compile(dialect=mssql.dialect()))
CREATE  SEQUENCE  my_seq  START  WITH  1 

对于整数主键生成,通常应优先选择 SQL Server 的IDENTITY构造而不是序列。

提示

T-SQL 的默认起始值为-2**63,而不是大多数其他 SQL 数据库中的 1。如果预期默认值是 1,则用户应明确设置Sequence.start

seq = Sequence("my_sequence", start=1)

从版本 1.4 开始:为Sequence添加了对 SQL Server 的支持

在 2.0 版本中更改:SQL Server 方言将不再隐式呈现“START WITH 1”用于CREATE SEQUENCE,这是在 1.4 版本中首次实现的行为。

VARCHAR / NVARCHAR 上的 MAX

SQL Server 支持特殊字符串“MAX”在VARCHARNVARCHAR数据类型中,以指示“可能的最大长度”。方言当前将此处理为基本类型中长度为“None”,而不是提供这些类型的特定于方言的版本,因此可以假定指定为VARCHAR(None)之类的基本类型在不使用特定于方言的类型的情况下,在多个后端上表现出“无长度”的行为。

要构建具有 MAX 长度的 SQL Server VARCHAR 或 NVARCHAR,请使用 None:

my_table = Table(
    'my_table', metadata,
    Column('my_data', VARCHAR(None)),
    Column('my_n_data', NVARCHAR(None))
)

字符串排序支持

基本字符串类型支持字符排序,由字符串参数“collation”指定:

from sqlalchemy import VARCHAR
Column('login', VARCHAR(32, collation='Latin1_General_CI_AS'))

当此列与Table关联时,该列的 CREATE TABLE 语句将产生:

login VARCHAR(32) COLLATE Latin1_General_CI_AS NULL

LIMIT/OFFSET 支持

MSSQL 从 SQL Server 2012 开始增加了对 LIMIT / OFFSET 的支持,通过“OFFSET n  ROWS”和“FETCH NEXT n ROWS”子句。如果检测到 SQL Server 2012 或更高版本,则 SQLAlchemy  会自动支持这些语法。

1.4 版本中更改:增加了对 SQL Server“OFFSET n ROWS”和“FETCH NEXT n ROWS”语法的支持。

对于仅指定 LIMIT 而不指定 OFFSET 的语句,所有版本的 SQL Server 都支持 TOP 关键字。当没有 OFFSET 子句时,此语法用于所有 SQL Server 版本。例如这样的语句:

select(some_table).limit(5)

将类似于以下内容呈现:

SELECT TOP 5 col1, col2.. FROM table

对于 SQL Server 2012 之前的版本,使用 LIMIT 和 OFFSET 或仅使用 OFFSET 的语句将使用ROW_NUMBER()窗口函数呈现。例如这样的语句:

select(some_table).order_by(some_table.c.col3).limit(5).offset(10)

将类似于以下内容呈现:

SELECT anon_1.col1, anon_1.col2 FROM (SELECT col1, col2,
ROW_NUMBER() OVER (ORDER BY col3) AS
mssql_rn FROM table WHERE t.x = :x_1) AS
anon_1 WHERE mssql_rn > :param_1 AND mssql_rn <= :param_2 + :param_1

请注意,无论是使用旧版还是新版 SQL Server 语法,使用 LIMIT 和/或 OFFSET 时,语句必须也有 ORDER BY,否则会引发CompileError

DDL 注释支持

支持注释,包括对Table.commentColumn.comment等属性的 DDL 呈现,以及反映这些注释的能力,假定正在使用受支持的 SQL Server 版本。如果在首次连接时检测到不受支持的版本(例如 Azure Synapse)(基于fn_listextendedproperty SQL 函数的存在),则会禁用注释支持,包括呈现和表注释反射,因为这两个功能依赖于并非所有后端类型都可用的 SQL Server 存储过程和函数。

要强制开启或关闭注释支持,绕过自动检测,请在 create_engine() 中设置参数 supports_comments

e = create_engine("mssql+pyodbc://u:p@dsn", supports_comments=False)

新版本 2.0 中:增加了对 SQL Server 方言的表和列注释的支持,包括 DDL 生成和反射。

事务隔离级别

所有 SQL Server 方言都支持通过方言特定参数create_engine.isolation_level(由create_engine() 接受)以及传递给 Connection.execution_options()Connection.execution_options.isolation_level 参数来设置事务隔离级别。该功能通过为每个新连接发出命令 SET TRANSACTION ISOLATION LEVEL 来实现。

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

engine = create_engine(
    "mssql+pyodbc://scott:tiger@ms_2008",
    isolation_level="REPEATABLE READ"
)

使用每个连接的执行选项来设置:

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

isolation_level 的有效值包括:

  • AUTOCOMMIT - pyodbc / pymssql 特有
  • READ COMMITTED
  • READ UNCOMMITTED
  • REPEATABLE READ
  • SERIALIZABLE
  • SNAPSHOT - SQL Server 特有

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

另请参阅

设置事务隔离级别,包括 DBAPI 自动提交

连接池的临时表 / 资源重置

SQLAlchemy Engine 对象使用的 QueuePool 连接池实现包含 返回时重置 行为,当连接返回到池中时将调用 DBAPI 的.rollback() 方法。虽然此回滚会清除前一个事务使用的即时状态,但它不涵盖更广泛范围的会话级状态,包括临时表以及其他服务器状态,如准备好的语句句柄和语句缓存。一个名为sp_reset_connection的未记录的 SQL Server 程序被认为是此问题的解决方法,它将重置建立在连接上的大部分会话状态,包括临时表。

要将sp_reset_connection安装为执行返回时重置的方法,可以使用 PoolEvents.reset() 事件钩子,如下例所示。将 create_engine.pool_reset_on_return 参数设置为None,以便自定义方案可以完全替换默认行为。自定义钩子实现在任何情况下调用.rollback(),因为通常重要的是 DBAPI 自身的提交/回滚跟踪将保持与事务状态一致:

from sqlalchemy import create_engine
from sqlalchemy import event
mssql_engine = create_engine(
    "mssql+pyodbc://scott:tiger⁵HHH@mssql2017:1433/test?driver=ODBC+Driver+17+for+SQL+Server",
    # disable default reset-on-return scheme
    pool_reset_on_return=None,
)
@event.listens_for(mssql_engine, "reset")
def _reset_mssql(dbapi_connection, connection_record, reset_state):
    if not reset_state.terminate_only:
        dbapi_connection.execute("{call sys.sp_reset_connection}")
    # so that the DBAPI itself knows that the connection has been
    # reset
    dbapi_connection.rollback()

在 2.0.0b3 版中更改:为 PoolEvents.reset() 事件添加了额外的状态参数,并且还确保对所有“重置”事件进行调用,因此它适用于自定义“重置”处理程序的地方。先前使用 PoolEvents.checkin() 处理程序的方案仍然可用。

另请参阅

返回时重置 - 在 连接池 文档中

可空性

MSSQL 支持三个级别的列可空性。默认的可空性允许空值,并且在 CREATE TABLE 构造中是显式的:

name VARCHAR(20) NULL

如果指定了nullable=None,则不做任何规定。换句话说,将使用数据库配置的默认值。这将呈现为:

name VARCHAR(20)

如果nullableTrueFalse,则列将分别为NULLNOT NULL

日期/时间处理

支持 DATE 和 TIME。根据大多数 MSSQL 驱动程序的要求,绑定参数将转换为 datetime.datetime()  对象,并且如果需要的话,结果将从字符串中处理。对于 MSSQL 2005 及之前版本,不可用 DATE 和 TIME 类型 - 如果检测到低于  2008 的服务器版本,则将为这些类型发出 DDL 作为 DATETIME。

大文本/二进制类型弃用

根据 SQL Server 2012/2014 文档NTEXTTEXTIMAGE 数据类型将在将来的发布中从 SQL Server 中删除。SQLAlchemy 通常将这些类型关联到 UnicodeTextTextClauseLargeBinary 数据类型。

为了适应这一变化,方言新增了一个名为 deprecate_large_types 的新标志,该标志将根据正在使用的服务器版本的检测自动设置,如果用户未设置其他值的话。该标志的行为如下:

  • 当此标志为 True 时,UnicodeTextTextClauseLargeBinary 数据类型在用于渲染 DDL 时,将分别呈现类型 NVARCHAR(max)VARCHAR(max)VARBINARY(max)。这是此标志添加后的新行为。
  • 当此标志为 False 时,UnicodeTextTextClauseLargeBinary 数据类型在用于渲染 DDL 时,将分别呈现类型 NTEXTTEXTIMAGE。这是这些类型的长期行为。
  • 标志在建立数据库连接之前以值 None 开始。如果方言在未设置标志的情况下用于渲染 DDL,则其解释方式与 False 相同。
  • 在第一次连接时,方言会检测是否正在使用 SQL Server 2012 或更高版本;如果标志仍处于 None,则根据是否检测到 2012 或更高版本来设置为 TrueFalse
  • 当创建方言时,可以将标志设置为 TrueFalse,通常通过 create_engine() 完成:
eng = create_engine("mssql+pymssql://user:pass@host/db",
                deprecate_large_types=True)
  • Complete control  over whether the “old” or “new” types are rendered is available in all  SQLAlchemy versions by using the UPPERCASE type objects instead: NVARCHAR, VARCHAR, VARBINARY, TEXT, NTEXT, IMAGE will always remain fixed and always output exactly that type.

Multipart Schema Names

SQL Server schemas sometimes require multiple parts to their “schema”  qualifier, that is, including the database name and owner name as  separate tokens, such as mydatabase.dbo.some_table. These multipart names can be set at once using the Table.schema argument of Table:

Table(
    "some_table", metadata,
    Column("q", String(50)),
    schema="mydatabase.dbo"
)

When performing operations such as table or component reflection, a  schema argument that contains a dot will be split into separate  “database” and “owner” components in order to correctly query the SQL  Server information schema tables, as these two values are stored  separately. Additionally, when rendering the schema name for DDL or SQL,  the two components will be quoted separately for case sensitive names  and other special characters. Given an argument as below:

Table(
    "some_table", metadata,
    Column("q", String(50)),
    schema="MyDataBase.dbo"
)

The above schema would be rendered as [MyDataBase].dbo, and also in reflection, would be reflected using “dbo” as the owner and “MyDataBase” as the database name.

To control how the schema name is broken into database / owner,  specify brackets (which in SQL Server are quoting characters) in the  name. Below, the “owner” will be considered as MyDataBase.dbo and the “database” will be None:

Table(
    "some_table", metadata,
    Column("q", String(50)),
    schema="[MyDataBase.dbo]"
)

To individually specify both database and owner name with special characters or embedded dots, use two sets of brackets:

Table(
    "some_table", metadata,
    Column("q", String(50)),
    schema="[MyDataBase.Period].[MyOwner.Dot]"
)

Changed in version 1.2: the SQL Server dialect now treats brackets as  identifier delimiters splitting the schema into separate database and  owner tokens, to allow dots within either name itself.

Legacy Schema Mode

Very old versions of the MSSQL dialect introduced the behavior such  that a schema-qualified table would be auto-aliased when used in a  SELECT statement; given a table:

account_table = Table(
    'account', metadata,
    Column('id', Integer, primary_key=True),
    Column('info', String(100)),
    schema="customer_schema"
)

this legacy mode of rendering would assume that  “customer_schema.account” would not be accepted by all parts of the SQL  statement, as illustrated below:

>>> eng = create_engine("mssql+pymssql://mydsn", legacy_schema_aliasing=True)
>>> print(account_table.select().compile(eng))
SELECT  account_1.id,  account_1.info
FROM  customer_schema.account  AS  account_1 

此行为模式现在默认关闭,因为似乎没有任何作用;但是,如果传统应用程序依赖于它,则可以使用create_engine()中的legacy_schema_aliasing参数来使用,如上所示。

自版本 1.4 起弃用:legacy_schema_aliasing标志现已弃用,并将在将来的版本中删除。

聚集索引支持

MSSQL 方言支持通过mssql_clustered选项生成聚集索引(和主键)。此选项适用于IndexUniqueConstraintPrimaryKeyConstraint。对于索引,此选项可以与mssql_columnstore结合使用以创建聚集列存储索引。

生成一个聚集索引:

Index("my_index", table.c.x, mssql_clustered=True)

将索引渲染为CREATE CLUSTERED INDEX my_index ON table (x)

要生成一个聚集主键,请使用:

Table('my_table', metadata,
      Column('x', ...),
      Column('y', ...),
      PrimaryKeyConstraint("x", "y", mssql_clustered=True))

例如,将表渲染为:

CREATE TABLE my_table (x INTEGER NOT NULL, y INTEGER NOT NULL,
                       PRIMARY KEY CLUSTERED (x, y))

类似地,我们可以使用以下方法生成一个聚类唯一约束:

Table('my_table', metadata,
      Column('x', ...),
      Column('y', ...),
      PrimaryKeyConstraint("x"),
      UniqueConstraint("y", mssql_clustered=True),
      )

要明确请求非聚集主键(例如,当需要单独的聚集索引时),请使用:

Table('my_table', metadata,
      Column('x', ...),
      Column('y', ...),
      PrimaryKeyConstraint("x", "y", mssql_clustered=False))

例如,将表渲染为:

CREATE TABLE my_table (x INTEGER NOT NULL, y INTEGER NOT NULL,
                       PRIMARY KEY NONCLUSTERED (x, y))

列存储索引支持

MSSQL 方言通过mssql_columnstore选项支持列存储索引。此选项适用于Index。它可以与mssql_clustered选项结合使用以创建聚集列存储索引。

要生成列存储索引:

Index("my_index", table.c.x, mssql_columnstore=True)

将索引渲染为CREATE COLUMNSTORE INDEX my_index ON table (x)

要生成一个聚集列存储索引,请不提供列:

idx = Index("my_index", mssql_clustered=True, mssql_columnstore=True)
# required to associate the index with the table
table.append_constraint(idx)

上述将索引渲染为CREATE CLUSTERED COLUMNSTORE INDEX my_index ON table

版本 2.0.18 中的新功能。

MSSQL 特定的索引选项

除了聚类外,MSSQL 方言还支持其他特殊选项用于Index

包括

mssql_include选项为给定的字符串名称渲染 INCLUDE(colname):

Index("my_index", table.c.x, mssql_include=['y'])

将索引渲染为CREATE INDEX my_index ON table (x) INCLUDE (y)

过滤索引

mssql_where选项为给定的字符串名称渲染 WHERE(condition):

Index("my_index", table.c.x, mssql_where=table.c.x > 10)

将索引渲染为CREATE INDEX my_index ON table (x) WHERE x > 10

版本 1.3.4 中的新功能。

索引排序

索引排序可通过功能表达式获得,例如:

Index("my_index", table.c.x.desc())

将索引渲染为CREATE INDEX my_index ON table (x DESC)

另请参阅

功能性索引

包括

mssql_include选项为给定的字符串名称渲染 INCLUDE(colname):

Index("my_index", table.c.x, mssql_include=['y'])

渲染索引为CREATE INDEX my_index ON table (x) INCLUDE (y)

过滤索引

mssql_where 选项为给定的字符串名称渲染 WHERE(condition):

Index("my_index", table.c.x, mssql_where=table.c.x > 10)

渲染索引为CREATE INDEX my_index ON table (x) WHERE x > 10

在 1.3.4 版中新增。

索引排序

可以通过函数表达式实现索引排序,例如:

Index("my_index", table.c.x.desc())

渲染索引为CREATE INDEX my_index ON table (x DESC)

另请参阅

功能索引

兼容性级别

MSSQL 支持在数据库级别设置兼容性级别的概念。这允许例如,在运行于 SQL2005 数据库服务器上时运行与 SQL2000 兼容的数据库。server_version_info 将始终返回数据库服务器版本信息(在此情况下为 SQL2005),而不是兼容性级别信息。因此,如果在向后兼容模式下运行,则 SQLAlchemy 可能会尝试使用数据库服务器无法解析的 T-SQL 语句。

触发器

SQLAlchemy 默认使用 OUTPUT INSERTED 获取通过 IDENTITY 列或其他服务器端默认值生成的新主键值。MS-SQL 不允许在具有触发器的表上使用 OUTPUT INSERTED。要在每个具有触发器的 Table 上禁用 OUTPUT INSERTED 的使用,请为其指定 implicit_returning=False

Table('mytable', metadata,
    Column('id', Integer, primary_key=True),
    # ...,
    implicit_returning=False
)

声明形式:

class MyClass(Base):
    # ...
    __table_args__ = {'implicit_returning':False}

行数支持 / ORM 版本控制

SQL Server 驱动程序可能有限的能力来返回更新或删除语句所影响的行数。

截至本文撰写时,PyODBC 驱动程序无法在使用 OUTPUT INSERTED 时返回行数。因此,SQLAlchemy 的先前版本在功能上存在限制,例如依赖准确的行数来匹配版本号与匹配行的“ORM 版本控制”功能。

SQLAlchemy 2.0 现在根据返回的 RETURNING  中到达的行数手动检索这些特定用例的“行数”;因此,虽然驱动程序仍具有此限制,但 ORM 版本控制功能不再受其影响。截至 SQLAlchemy  2.0.5,已完全重新启用了 pyodbc 驱动程序的 ORM 版本控制功能。

在 2.0.5 版更改:对于 pyodbc 驱动程序,已恢复 ORM 版本控制支持。先前,ORM 刷新期间会发出警告,说明不支持版本控制。

启用快照隔离

SQL Server  具有默认的事务隔离模式,锁定整个表,并导致即使是稍微并发的应用程序也具有长时间持有的锁定和频繁的死锁。为了支持现代级别的并发性,建议为整个数据库启用快照隔离。这通过在  SQL 提示符下执行以下 ALTER DATABASE 命令来完成:

ALTER DATABASE MyDatabase SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE MyDatabase SET READ_COMMITTED_SNAPSHOT ON

关于 SQL Server 快照隔离的背景信息,请访问 msdn.microsoft.com/en-us/library/ms175095.aspx

SQL Server SQL 构造

对象名称 描述
try_cast(expression, type_) 为支持的后端生成一个 TRY_CAST 表达式;这是一个返回 NULL 的 CAST,用于不可转换的转换。
function sqlalchemy.dialects.mssql.try_cast(expression: _ColumnExpressionOrLiteralArgument[Any], type_: _TypeEngineArgument[_T]) → TryCast[_T]

为支持的后端生成一个 TRY_CAST 表达式;这是一个返回 NULL 的 CAST,用于不可转换的转换。

在 SQLAlchemy 中,此构造仅受 SQL Server 方言支持,并且如果在其他包含的后端上使用,则会引发 CompileError。但是,第三方后端也可能支持此构造。

提示

由于 try_cast() 来源于 SQL Server 方言,因此它既可以从 sqlalchemy. 导入,也可以从 sqlalchemy.dialects.mssql 导入。

try_cast() 返回 TryCast 的实例,并且通常表现得与 Cast 构造类似;在 SQL 层面,CASTTRY_CAST 之间的区别在于 TRY_CAST 对于不可转换的表达式(例如,尝试将字符串 "hi" 转换为整数值)返回 NULL。

例如:

from sqlalchemy import select, try_cast, Numeric
stmt = select(
    try_cast(product_table.c.unit_price, Numeric(10, 4))
)

上述内容在 Microsoft SQL Server 上呈现为:

SELECT TRY_CAST (product_table.unit_price AS NUMERIC(10, 4))
FROM product_table

从版本 2.0.14 开始:try_cast()已从 SQL Server 方言泛化为一个通用构造,可能由其他方言支持。


SqlAlchemy 2.0 中文文档(五十二)(6)https://developer.aliyun.com/article/1563145

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
相关文章
|
4月前
|
SQL NoSQL 数据库
SqlAlchemy 2.0 中文文档(五十二)(2)
SqlAlchemy 2.0 中文文档(五十二)
37 0
|
4月前
|
SQL JSON 数据库
SqlAlchemy 2.0 中文文档(五十二)(6)
SqlAlchemy 2.0 中文文档(五十二)
24 0
|
4月前
|
SQL 测试技术 数据库
SqlAlchemy 2.0 中文文档(五十二)(1)
SqlAlchemy 2.0 中文文档(五十二)
26 0
|
4月前
|
SQL 数据库连接 Linux
SqlAlchemy 2.0 中文文档(五十二)(7)
SqlAlchemy 2.0 中文文档(五十二)
67 0
|
4月前
|
SQL JSON 关系型数据库
SqlAlchemy 2.0 中文文档(五十二)(3)
SqlAlchemy 2.0 中文文档(五十二)
36 0
|
4月前
|
SQL 数据库连接 Linux
SqlAlchemy 2.0 中文文档(五十二)(4)
SqlAlchemy 2.0 中文文档(五十二)
64 0
|
4月前
|
SQL 安全 关系型数据库
SqlAlchemy 2.0 中文文档(五十三)(4)
SqlAlchemy 2.0 中文文档(五十三)
35 0
|
4月前
|
SQL 关系型数据库 API
SqlAlchemy 2.0 中文文档(五十三)(2)
SqlAlchemy 2.0 中文文档(五十三)
28 0
|
4月前
|
SQL 安全 关系型数据库
SqlAlchemy 2.0 中文文档(五十三)(5)
SqlAlchemy 2.0 中文文档(五十三)
41 0
|
4月前
|
关系型数据库 MySQL API
SqlAlchemy 2.0 中文文档(五十三)(1)
SqlAlchemy 2.0 中文文档(五十三)
53 0