SqlAlchemy 2.0 中文文档(七)(3)

简介: SqlAlchemy 2.0 中文文档(七)

SqlAlchemy 2.0 中文文档(七)(2)https://developer.aliyun.com/article/1560922


使用非映射数据类字段

当使用声明性数据类时,类上也可以使用非映射字段,这些字段将成为数据类构造过程的一部分,但不会被映射。任何未使用Mapped的字段都将被映射过程忽略。在下面的示例中,字段ctrl_onectrl_two将成为对象的实例级状态的一部分,但不会由 ORM 持久化:

from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import registry
reg = registry()
@reg.mapped_as_dataclass
class Data:
    __tablename__ = "data"
    id: Mapped[int] = mapped_column(init=False, primary_key=True)
    status: Mapped[str]
    ctrl_one: Optional[str] = None
    ctrl_two: Optional[str] = None

上面的Data实例可以创建为:

d1 = Data(status="s1", ctrl_one="ctrl1", ctrl_two="ctrl2")

一个更实际的例子可能是结合数据类的InitVar特性和__post_init__()特性来接收仅初始化字段,这些字段可用于组成持久化数据。在下面的示例中,User类使用idnamepassword_hash作为映射特性,但使用仅初始化的passwordrepeat_password字段表示用户创建过程(注意:要运行此示例,请将函数your_crypt_function_here()替换为第三方加密函数,如bcryptargon2-cffi):

from dataclasses import InitVar
from typing import Optional
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import registry
reg = registry()
@reg.mapped_as_dataclass
class User:
    __tablename__ = "user_account"
    id: Mapped[int] = mapped_column(init=False, primary_key=True)
    name: Mapped[str]
    password: InitVar[str]
    repeat_password: InitVar[str]
    password_hash: Mapped[str] = mapped_column(init=False, nullable=False)
    def __post_init__(self, password: str, repeat_password: str):
        if password != repeat_password:
            raise ValueError("passwords do not match")
        self.password_hash = your_crypt_function_here(password)

上述对象使用参数passwordrepeat_password创建,这些参数被立即消耗,以便生成password_hash变量:

>>> u1 = User(name="some_user", password="xyz", repeat_password="xyz")
>>> u1.password_hash
'$6$9ppc... (example crypted string....)'

从版本 2.0.0rc1 开始更改:当使用registry.mapped_as_dataclass()MappedAsDataclass时,可以包括不包括Mapped注释的字段,这些字段将被视为生成的数据类的一部分,但不会被映射,无需指定__allow_unmapped__类属性。以前的 2.0 beta 版本将要求明确存在此属性,即使此属性的目的仅是允许旧版 ORM 类型映射继续运行。### 与诸如 Pydantic 等替代数据类提供者集成

警告

Pydantic 的 dataclass 层与 SQLAlchemy 的类仪器化不完全兼容,需要额外的内部更改,许多功能,例如相关集合,可能无法正常工作。

为了与 Pydantic 兼容,请考虑使用SQLModel ORM,该 ORM 基于 SQLAlchemy ORM 构建,使用 Pydantic,其中包括明确解决这些不兼容性的特殊实现细节。

SQLAlchemy 的MappedAsDataclass类和registry.mapped_as_dataclass()方法调用直接进入 Python 标准库 dataclasses.dataclass 类装饰器,经过类的声明性映射处理后。此函数调用可以通过MappedAsDataclass作为类关键字参数以及registry.mapped_as_dataclass()接受的dataclass_callable参数交换为备用 dataclasses 提供程序,例如 Pydantic 的提供程序:

from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import MappedAsDataclass
from sqlalchemy.orm import registry
class Base(
    MappedAsDataclass,
    DeclarativeBase,
    dataclass_callable=pydantic.dataclasses.dataclass,
):
    pass
class User(Base):
    __tablename__ = "user"
    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str]

上述 User 类将被应用为一个数据类,使用 Pydantic 的 pydantic.dataclasses.dataclasses 可调用。该过程对映射类以及从MappedAsDataclass扩展的混合类或直接应用了registry.mapped_as_dataclass()的类都可用。

新版本 2.0.4 中:为MappedAsDataclassregistry.mapped_as_dataclass()添加了 dataclass_callable 类和方法参数,并调整了一些数据类内部,以适应更严格的数据类函数,例如 Pydantic 的函数。

类级特性配置

对 dataclasses 特性的支持是部分的。当前支持的特性包括 initrepreqorderunsafe_hash 特性,match_argskw_only 在 Python 3.10+ 上受支持。当前不支持的特性包括 frozenslots 特性。

当使用与MappedAsDataclass配合使用的混合类形式时,类配置参数被作为类级参数传递:

from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import MappedAsDataclass
class Base(DeclarativeBase):
    pass
class User(MappedAsDataclass, Base, repr=False, unsafe_hash=True):
  """User class will be converted to a dataclass"""
    __tablename__ = "user_account"
    id: Mapped[int] = mapped_column(init=False, primary_key=True)
    name: Mapped[str]

当使用装饰器形式与registry.mapped_as_dataclass()一起使用时,类配置参数直接传递给装饰器:

from sqlalchemy.orm import registry
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
reg = registry()
@reg.mapped_as_dataclass(unsafe_hash=True)
class User:
  """User class will be converted to a dataclass"""
    __tablename__ = "user_account"
    id: Mapped[int] = mapped_column(init=False, primary_key=True)
    name: Mapped[str]

有关 dataclass 类选项的背景,请参阅dataclasses文档中的@dataclasses.dataclass

属性配置

SQLAlchemy 本地 dataclasses 与普通 dataclasses 不同之处在于,要映射的属性在所有情况下都使用Mapped通用注释容器描述。映射遵循与使用 mapped_column() 声明的声明性表格文档中记录的相同形式,支持所有mapped_column()Mapped的功能。

此外,ORM 属性配置构造包括mapped_column()relationship()composite()支持每个属性字段选项,包括initdefaultdefault_factoryrepr。这些参数的名称如PEP 681中指定的那样固定。功能与 dataclasses 等效:

  • init,比如mapped_column.initrelationship.init,如果为 False,表示该字段不应该是__init__()方法的一部分。
  • default,比如mapped_column.defaultrelationship.default,表示字段的默认值,作为__init__()方法的关键字参数传递。
  • default_factory,比如mapped_column.default_factoryrelationship.default_factory,表示一个可调用函数,将被调用以生成一个新的默认值,如果参数未明确传递给__init__()方法。
  • repr 默认为 True,表示该字段应该是生成的__repr__()方法的一部分。

与 dataclasses 的另一个关键区别是,属性的默认值必须使用 ORM 构造函数的 default 参数进行配置,例如 mapped_column(default=None)。不支持接受简单 Python 值作为默认值的类似 dataclass 语法,而不使用 @dataclases.field()

作为使用 mapped_column() 的示例,下面的映射将生成一个 __init__() 方法,该方法仅接受字段 namefullname,其中 name 是必需的,并且可以按位置传递,而 fullname 是可选的。我们预期的由数据库生成的 id 字段根本不是构造函数的一部分:

from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import registry
reg = registry()
@reg.mapped_as_dataclass
class User:
    __tablename__ = "user_account"
    id: Mapped[int] = mapped_column(init=False, primary_key=True)
    name: Mapped[str]
    fullname: Mapped[str] = mapped_column(default=None)
# 'fullname' is optional keyword argument
u1 = User("name")
列默认值

为了适应 default 参数与 Column.default 构造函数现有参数的名称重叠,mapped_column() 构造函数通过添加一个新参数 mapped_column.insert_default 来消除两个名称之间的歧义,该参数将直接填充到 Column.default 参数中,独立于 mapped_column.default 上的设置,后者始终用于数据类配置。例如,要配置一个 datetime 列,其中 Column.default 设置为 func.utc_timestamp() SQL 函数,但构造函数中该参数是可选的:

from datetime import datetime
from sqlalchemy import func
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import registry
reg = registry()
@reg.mapped_as_dataclass
class User:
    __tablename__ = "user_account"
    id: Mapped[int] = mapped_column(init=False, primary_key=True)
    created_at: Mapped[datetime] = mapped_column(
        insert_default=func.utc_timestamp(), default=None
    )

使用上述映射,对于一个新的 User 对象的 INSERT,如果没有传递 created_at 的参数,操作将如下进行:

>>> with Session(e) as session:
...     session.add(User())
...     session.commit()
BEGIN  (implicit)
INSERT  INTO  user_account  (created_at)  VALUES  (utc_timestamp())
[generated  in  0.00010s]  ()
COMMIT 
与 Annotated 集成

在将整个列声明映射到 Python 类型介绍的方法说明了如何使用 PEP 593 中的 Annotated 对象将整个 mapped_column() 构建打包以供重复使用。此功能支持 dataclasses 功能。然而,该功能的一个方面在使用类型工具时需要一个解决方法,即 PEP 681 特定参数 initdefaultreprdefault_factory 必须 在右侧,被打包到显式的 mapped_column() 构建中,以便类型工具正确解释属性。例如,下面的方法在运行时将完美地工作,但是类型工具会认为 User() 构造无效,因为它们没有看到 init=False 参数:

from typing import Annotated
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import registry
# typing tools will ignore init=False here
intpk = Annotated[int, mapped_column(init=False, primary_key=True)]
reg = registry()
@reg.mapped_as_dataclass
class User:
    __tablename__ = "user_account"
    id: Mapped[intpk]
# typing error: Argument missing for parameter "id"
u1 = User()

相反,mapped_column() 必须在右侧也存在,并且必须显式设置 mapped_column.init;其他参数可以保留在 Annotated 结构中:

from typing import Annotated
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import registry
intpk = Annotated[int, mapped_column(primary_key=True)]
reg = registry()
@reg.mapped_as_dataclass
class User:
    __tablename__ = "user_account"
    # init=False and other pep-681 arguments must be inline
    id: Mapped[intpk] = mapped_column(init=False)
u1 = User()
列默认值

为了适应 default 参数与 Column.default 构造函数的现有参数的名称重叠,mapped_column() 构造函数通过添加一个新参数 mapped_column.insert_default 来消除这两个名称之间的歧义,该参数将直接填充到 Column.default 参数中,而与 mapped_column.default 设置无关,后者始终用于 dataclasses 配置。例如,要配置一个 datetime 列,并将 Column.default 设置为 func.utc_timestamp() SQL 函数,但构造函数中该参数是可选的:

from datetime import datetime
from sqlalchemy import func
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import registry
reg = registry()
@reg.mapped_as_dataclass
class User:
    __tablename__ = "user_account"
    id: Mapped[int] = mapped_column(init=False, primary_key=True)
    created_at: Mapped[datetime] = mapped_column(
        insert_default=func.utc_timestamp(), default=None
    )

在上述映射中,当未传递 created_at 参数的情况下,对新的 User 对象进行 INSERT 操作如下进行:

>>> with Session(e) as session:
...     session.add(User())
...     session.commit()
BEGIN  (implicit)
INSERT  INTO  user_account  (created_at)  VALUES  (utc_timestamp())
[generated  in  0.00010s]  ()
COMMIT 
Annotated 的集成

在将整个列声明映射到 Python 类型中介绍的方法说明了如何使用PEP 593 Annotated对象来打包整个mapped_column()结构以供重用。该功能与数据类功能一起使用。然而,该功能的一个方面在使用类型工具时需要一个解决方法,即PEP 681特定的参数initdefaultreprdefault_factory 必须 在右侧,打包到显式的mapped_column()构造中,以便类型工具正确解释属性。例如,下面的方法在运行时将完美运行,但是类型工具将认为User()构造无效,因为它们看不到init=False参数的存在:

from typing import Annotated
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import registry
# typing tools will ignore init=False here
intpk = Annotated[int, mapped_column(init=False, primary_key=True)]
reg = registry()
@reg.mapped_as_dataclass
class User:
    __tablename__ = "user_account"
    id: Mapped[intpk]
# typing error: Argument missing for parameter "id"
u1 = User()

相反,mapped_column()也必须出现在右侧,并在Annotated结构中包含对mapped_column.init的显式设置;其他参数可以保留在Annotated结构中:

from typing import Annotated
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import registry
intpk = Annotated[int, mapped_column(primary_key=True)]
reg = registry()
@reg.mapped_as_dataclass
class User:
    __tablename__ = "user_account"
    # init=False and other pep-681 arguments must be inline
    id: Mapped[intpk] = mapped_column(init=False)
u1 = User()

使用混入和抽象超类

MappedAsDataclass映射类中使用的任何混入或基类,其中包括Mapped属性,必须本身是MappedAsDataclass层次结构的一部分,例如,在下面的示例中使用混入:

class Mixin(MappedAsDataclass):
    create_user: Mapped[int] = mapped_column()
    update_user: Mapped[Optional[int]] = mapped_column(default=None, init=False)
class Base(DeclarativeBase, MappedAsDataclass):
    pass
class User(Base, Mixin):
    __tablename__ = "sys_user"
    uid: Mapped[str] = mapped_column(
        String(50), init=False, default_factory=uuid4, primary_key=True
    )
    username: Mapped[str] = mapped_column()
    email: Mapped[str] = mapped_column()

Python 类型检查器,支持PEP 681,否则将不考虑非数据类混入的属性作为数据类的一部分。

从版本 2.0.8 开始已弃用:在MappedAsDataclassregistry.mapped_as_dataclass()层次结构中使用混入和抽象基类,这些类本身不是数据类,这是不推荐的,因为这些字段不被PEP 681支持为数据类的一部分。对于这种情况会发出警告,以后会成为错误。

另请参阅

当将转换为数据类时,属性源自不是数据类的超类。 - 关于原因的背景

关系配置

Mapped注解与relationship()结合使用的方式与基本关系模式中描述的相同。当将基于集合的relationship()指定为可选关键字参数时,必须传递relationship.default_factory参数,并且它必须引用要使用的集合类。如果默认值是None,则多对一和标量对象引用可以使用relationship.default:

from typing import List
from sqlalchemy import ForeignKey
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import registry
from sqlalchemy.orm import relationship
reg = registry()
@reg.mapped_as_dataclass
class Parent:
    __tablename__ = "parent"
    id: Mapped[int] = mapped_column(primary_key=True)
    children: Mapped[List["Child"]] = relationship(
        default_factory=list, back_populates="parent"
    )
@reg.mapped_as_dataclass
class Child:
    __tablename__ = "child"
    id: Mapped[int] = mapped_column(primary_key=True)
    parent_id: Mapped[int] = mapped_column(ForeignKey("parent.id"))
    parent: Mapped["Parent"] = relationship(default=None)

上述映射将在构造新的Parent()对象时为Parent.children生成一个空列表,当构造新的Child()对象时,如果不传递parent,则Child.parent将生成一个None值。

虽然relationship.default_factory可以自动从relationship()本身的给定集合类中派生,但这会与数据类兼容性破坏,因为relationship.default_factoryrelationship.default的存在决定了参数在渲染为__init__()方法时是必需还是可选。

使用非映射数据类字段

当使用声明性数据类时,也可以在类上使用非映射字段,这些字段将成为数据类构造过程的一部分,但不会被映射。任何不使用Mapped的字段都将被映射过程忽略。在下面的示例中,字段ctrl_onectrl_two将成为对象的实例级状态的一部分,但不会被 ORM 持久化:

from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import registry
reg = registry()
@reg.mapped_as_dataclass
class Data:
    __tablename__ = "data"
    id: Mapped[int] = mapped_column(init=False, primary_key=True)
    status: Mapped[str]
    ctrl_one: Optional[str] = None
    ctrl_two: Optional[str] = None

上面的Data实例可以创建为:

d1 = Data(status="s1", ctrl_one="ctrl1", ctrl_two="ctrl2")

更真实的示例可能是结合 Dataclasses 的InitVar特性和__post_init__()特性来使用仅初始化的字段,这些字段可以用于组合持久化数据。在下面的示例中,User类使用idnamepassword_hash作为映射特性声明,但使用了仅初始化的passwordrepeat_password字段来表示用户创建过程(注意:要运行此示例,请将函数your_crypt_function_here()替换为第三方加密函数,如bcryptargon2-cffi):

from dataclasses import InitVar
from typing import Optional
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import registry
reg = registry()
@reg.mapped_as_dataclass
class User:
    __tablename__ = "user_account"
    id: Mapped[int] = mapped_column(init=False, primary_key=True)
    name: Mapped[str]
    password: InitVar[str]
    repeat_password: InitVar[str]
    password_hash: Mapped[str] = mapped_column(init=False, nullable=False)
    def __post_init__(self, password: str, repeat_password: str):
        if password != repeat_password:
            raise ValueError("passwords do not match")
        self.password_hash = your_crypt_function_here(password)

上述对象使用了参数passwordrepeat_password,这些参数首先被使用,以便生成password_hash变量:

>>> u1 = User(name="some_user", password="xyz", repeat_password="xyz")
>>> u1.password_hash
'$6$9ppc... (example crypted string....)'

从版本 2.0.0rc1 开始更改:当使用registry.mapped_as_dataclass()MappedAsDataclass时,可以包括不包含Mapped注释的字段,这些字段将被视为生成的 dataclass 的一部分,但不会被映射,无需另外指示__allow_unmapped__类属性。先前的 2.0 beta 版本将要求明确包含此属性,即使此属性的目的仅是允许旧的 ORM 类型映射继续工作。

与 Pydantic 等替代 Dataclass 提供程序集成

警告

Pydantic 的 dataclass 层与 SQLAlchemy 的类仪器化不完全兼容,需要额外的内部更改,许多功能,如相关集合,可能无法正常工作。

为了与 Pydantic 兼容,请考虑使用SQLModel ORM,它是在 SQLAlchemy ORM 的基础上构建的 Pydantic,其中包含了专门解决这些不兼容性的实现细节。

SQLAlchemy 的MappedAsDataclass类和registry.mapped_as_dataclass()方法调用直接进入 Python 标准库的dataclasses.dataclass类装饰器中,声明性映射过程应用到类之后。此函数调用可以用 Pydantic 等替代数据类提供程序替换,使用MappedAsDataclass作为类关键字参数接受的dataclass_callable参数,以及registry.mapped_as_dataclass()同样接受的参数:

from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import MappedAsDataclass
from sqlalchemy.orm import registry
class Base(
    MappedAsDataclass,
    DeclarativeBase,
    dataclass_callable=pydantic.dataclasses.dataclass,
):
    pass
class User(Base):
    __tablename__ = "user"
    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str]

上述的User类将被应用为一个数据类,使用 Pydantic 的pydantic.dataclasses.dataclasses可调用。此过程对于映射类和扩展自MappedAsDataclass或直接应用了registry.mapped_as_dataclass()的混入类都可用。

2.0.4 版本中的新内容:为MappedAsDataclassregistry.mapped_as_dataclass()添加了dataclass_callable类和方法参数,并调整了一些数据类内部,以适应更严格的数据类函数,例如 Pydantic 的函数。


SqlAlchemy 2.0 中文文档(七)(4)https://developer.aliyun.com/article/1560926

相关文章
|
5月前
|
人工智能 IDE 定位技术
AI IDE正式上线!通义灵码开箱即用
通义灵码AI IDE现已正式上线,用户可免费下载使用。作为AI原生开发环境工具,它深度适配千问3大模型,集成通义灵码插件能力,支持编程智能体、行间建议预测和行间会话等功能。其核心亮点包括:支持最强开源模型千问3,具备MCP工具调用能力;开箱即用的智能编码助手;自带编程智能体模式,端到端完成编码任务;长期记忆、NES行间预测及Inline Chat功能,大幅提升编程效率。目前,通义灵码插件下载量超1500万,生成代码超30亿行,广泛应用于企业开发场景。
AI IDE正式上线!通义灵码开箱即用
|
缓存 NoSQL 关系型数据库
redis和缓存及相关问题和解决办法 什么是缓存预热、缓存穿透、缓存雪崩、缓存击穿
本文深入探讨了Redis缓存的相关知识,包括缓存的概念、使用场景、可能出现的问题(缓存预热、缓存穿透、缓存雪崩、缓存击穿)及其解决方案。
823 0
redis和缓存及相关问题和解决办法 什么是缓存预热、缓存穿透、缓存雪崩、缓存击穿
|
SQL 移动开发 前端开发
基于Jeecg-boot前后端分离的flowable流程管理平台主页调整
基于Jeecg-boot前后端分离的flowable流程管理平台主页调整
187 0
|
机器学习/深度学习 数据采集 算法
一文搞懂 卷积神经网络 批归一化 丢弃法
这篇文章详细介绍了卷积神经网络中的批归一化(Batch Normalization)和丢弃法(Dropout),包括它们的计算过程、作用、优势以及如何在飞桨框架中应用这些技术来提高模型的稳定性和泛化能力,并提供了网络结构定义和参数计算的示例。
|
11月前
|
Ubuntu Linux 虚拟化
CentOS7扩容踩坑记录(最后只有ubuntu成功)
这篇博客记录了一次尝试给CentOS根分区扩容的过程。作者在VMware中扩展了虚拟磁盘,但最终未能成功将新分区合并到现有卷组中,因为原有分区未创建物理卷(PV)和卷组(VG)。过程中遇到了多个问题,如分区文件正在使用中等。最终作者提醒读者在操作前务必先检查当前的分区和卷组状态。
233 4
CentOS7扩容踩坑记录(最后只有ubuntu成功)
|
安全 Python
FastAPI安全性揭秘:如何用Python构建坚不可摧的Web应用?
【8月更文挑战第31天】在现代Web开发中,确保应用安全稳定至关重要。FastAPI作为高性能Python Web框架,提供了认证授权、数据验证、CSRF保护及HTTPS支持等安全机制。本文将深入探讨这些特性,并通过示例代码展示如何利用FastAPI构建安全可靠的Web应用。 FastAPI的安全性涵盖多个方面:通过认证授权机制验证用户身份并控制访问权限;利用数据验证功能防止恶意输入;启用CSRF保护避免跨站请求伪造攻击;支持HTTPS增强应用安全性。示例代码展示了如何使用JWT进行认证授权、如何通过`Body`验证请求数据、如何启用CSRF保护以及如何配置HTTPS支持。
592 0
|
图形学
【实现100个unity特效】shader实现3D物品闪光和描边效果
【实现100个unity特效】shader实现3D物品闪光和描边效果
444 0
|
SQL 存储 测试技术
SqlAlchemy 2.0 中文文档(五十七)(4)
SqlAlchemy 2.0 中文文档(五十七)
341 0
[UE 虚幻引擎] DTLoadFbx 运行时加载FBX本地模型插件说明
该插件支持在运行时动态加载FBX模型,无需预先打包。通过新建Actor并添加DT Runtime Fbx Component,然后调用LoadFile函数加载模型路径(不支持动画)。加载时可选择是否创建碰撞体,该组件基于UProceduralMeshComponent,提供与PMC相似的设置。启用异步计算(Use Async Cooking)可加速碰撞体生成。
594 0
|
人工智能
【教育革新】阿里“通义听悟”:高校师生的智能助手,免费赠送500小时转写时长!
阿里云启动“通义听悟高校公益计划”,向中国大陆高校师生提供免费的智能学习工具。拥有edu.cn邮箱的师生可获500小时音视频转写时长和200G存储空间,借助AI技术加速学习与科研。该产品日处理字符数达20亿字,成为学生和教师的高效辅助工具,推动教育领域数字化进程。此计划旨在提升教育资源获取性和学习效率,创造智能化学习环境。
684 1