SqlAlchemy 2.0 中文文档(八十)(5)

简介: SqlAlchemy 2.0 中文文档(八十)

SqlAlchemy 2.0 中文文档(八十)(4)https://developer.aliyun.com/article/1559882


连接池默认不再是线程本地的

0.4 版本不幸默认设置为 pool_threadlocal=True,导致在单个线程中使用多个 Sessions 时出现意外行为。此标志在 0.5 版本中默认关闭。要重新启用 0.4 版本的行为,请在 create_engine() 中指定 pool_threadlocal=True,或者通过 strategy="threadlocal" 使用 “threadlocal” 策略。

*args 被接受,*args 不再被接受

method(\*args)method([args]) 的策略是,如果方法接受一个表示固定结构的可变长度项集合,则采用 \*args。如果方法接受一个数据驱动的可变长度项集合,则采用 [args]

  • 各种 Query.options() 函数 eagerload(), eagerload_all(), lazyload(), contains_eager(), defer(), undefer() 现在都接受可变长度的 \*keys 作为参数,这允许使用描述符来制定路径,例如:
query.options(eagerload_all(User.orders, Order.items, Item.keywords))
  • 为了向后兼容性,仍然接受单个数组参数。
  • 类似地,Query.join()Query.outerjoin() 方法现在接受可变长度的 *args,为了向后兼容性,现在只接受单个数组:
query.join("orders", "items")
query.join(User.orders, Order.items)
  • 列上的 in_() 方法和类似方法现在只接受列表参数。不再接受 \*args

已移除

  • entity_name - 这个特性一直存在问题,很少被使用。0.5 版本更深入地揭示了 entity_name 的问题,导致其被移除。如果需要为单个类使用不同的映射,将类拆分为单独的子类并分别映射它们。一个示例在  [wiki:UsageRecipes/EntityName] 中。有关背景的更多信息请参阅 https://groups.google.c  om/group/sqlalchemy/browse_thread/thread/9e23a0641a88b96d? hl=en 。
  • get()/load() 清理
    load() 方法已被移除。它的功能有点随意,基本上是从 Hibernate 复制过来的,在那里也不是一个特别有意义的方法。
    要获得等效功能:
x = session.query(SomeClass).populate_existing().get(7)
  • Session.get(cls, id)Session.load(cls, id) 已被移除。Session.get()session.query(cls).get(id) 是多余的。
    MapperExtension.get() 也已被移除(MapperExtension.load() 也是)。要覆盖 Query.get() 的功能,使用子类:
class MyQuery(Query):
    def get(self, ident): ...
session = sessionmaker(query_cls=MyQuery)()
ad1 = session.query(Address).get(1)
  • sqlalchemy.orm.relation()
    下列已弃用的关键字参数已被移除:
    foreignkey, association, private, attributeext, is_backref
    特别地,attributeext 被替换为 extension - AttributeExtension 类现在在公共 API 中。
  • session.Query()
    下列已弃用的函数已被移除:
    list,  scalar, count_by, select_whereclause, get_by, select_by, join_by,  selectfirst, selectone, select, execute, select_statement, select_text,  join_to, join_via, selectfirst_by, selectone_by, apply_max, apply_min,  apply_avg, apply_sum
    另外,join()outerjoin()add_entity()add_column()id 关键字参数已被移除。要将 Query 中的表别名定位到结果列,使用 aliased 构造:
from sqlalchemy.orm import aliased
address_alias = aliased(Address)
print(session.query(User, address_alias).join((address_alias, User.addresses)).all())
  • sqlalchemy.orm.Mapper
  • instances()
  • get_session() - 这个方法并不是很显著,但会将延迟加载与特定会话关联起来,即使父对象完全分离,当使用 scoped_session() 或旧的 SessionContextExt 等扩展时。有些应用程序可能依赖于这种行为,但现在可能不再按预期工作;但更好的编程实践是始终确保对象在会话中存在,如果需要从它们的属性访问数据库。
  • mapper(MyClass, mytable)
    映射类不再使用“c”类属性进行仪器化; 例如MyClass.c
  • sqlalchemy.orm.collections
    _prepare_instrumentation 别名 prepare_instrumentation 已被移除。
  • sqlalchemy.orm
    移除了EXT_PASS别名EXT_CONTINUE
  • sqlalchemy.engine
    DefaultDialect.preexecute_sequences.preexecute_pk_sequences的别名已被移除。
    已移除了弃用的 engine_descriptors()函数。
  • sqlalchemy.ext.activemapper
    模块已移除。
  • sqlalchemy.ext.assignmapper
    模块已移除。
  • sqlalchemy.ext.associationproxy
    代理的.append(item, \**kw)上的关键字参数传递已被移除,现在只是.append(item)
  • sqlalchemy.ext.selectresultssqlalchemy.mods.selectresults
    模块已移除。
  • sqlalchemy.ext.declarative
    declared_synonym()已移除。
  • sqlalchemy.ext.sessioncontext
    模块已移除。
  • sqlalchemy.log
    SADeprecationWarning别名sqlalchemy.exc.SADeprecationWarning已被移除。
  • sqlalchemy.exc
    exc.AssertionError已移除,使用被 Python 内置的同名替换。
  • sqlalchemy.databases.mysql
    已弃用的get_version_info方言方法已被移除。

重命名或移动

  • sqlalchemy.exceptions现在是sqlalchemy.exc
    该模块在 0.6 之前仍可使用旧名称导入。
  • FlushErrorConcurrentModificationErrorUnmappedColumnError -> sqlalchemy.orm.exc
    这些异常已移至 orm 包。导入sqlalchemy.orm将在 0.6 之前为兼容性安装 sqlalchemy.exc 的别名。
  • sqlalchemy.logging -> sqlalchemy.log
    此内部模块已重命名。在使用 py2app 等扫描导入的工具打包 SA 时,不再需要特殊处理。
  • session.Query().iterate_instances() -> session.Query().instances().

已弃用

  • Session.save()Session.update()Session.save_or_update()
    所有三个被Session.add()替换
  • sqlalchemy.PassiveDefault
    使用Column(server_default=...)在底层转换为sqlalchemy.DefaultClause()
  • session.Query().iterate_instances()。已重命名为instances().

主要文档更改

文档的一些部分已被完全重写,可以作为新 ORM 功能的介绍。特别是QuerySession对象在 API 和行为上有一些明显的差异,这些差异从根本上改变了许多基本操作的方式,特别是构建高度定制的 ORM 查询和处理过时的会话状态、提交和回滚。

弃用来源

另一个信息来源在一系列单元测试中记录了一些常见Query模式的最新用法;此文件可在[source:sqlalchemy/trunk/test/orm/test_deprecations.py]中查看。

要求更改

  • Python 2.4 或更高版本是必需的。SQLAlchemy 0.4 系列是最后一个支持 Python 2.3 的版本。

对象关系映射

  • Query 中的列级表达式。 - 如 教程 中详细说明的,Query 具有创建特定 SELECT 语句的能力,而不仅仅是针对完整行的语句:
session.query(User.name, func.count(Address.id).label("numaddresses")).join(
    Address
).group_by(User.name)
  • 任何多列/实体查询返回的元组都是命名元组:
for row in (
    session.query(User.name, func.count(Address.id).label("numaddresses"))
    .join(Address)
    .group_by(User.name)
):
    print("name", row.name, "number", row.numaddresses)
  • Query 有一个 statement 访问器,以及一个 subquery() 方法,允许 Query 用于创建更复杂的组合:
subq = (
    session.query(Keyword.id.label("keyword_id"))
    .filter(Keyword.name.in_(["beans", "carrots"]))
    .subquery()
)
recipes = session.query(Recipe).filter(
    exists()
    .where(Recipe.id == recipe_keywords.c.recipe_id)
    .where(recipe_keywords.c.keyword_id == subq.c.keyword_id)
)
  • 推荐使用显式 ORM 别名进行别名连接 - aliased() 函数生成一个类的“别名”,允许与 ORM 查询一起对别名进行精细控制。虽然仍然可以使用表级别的别名(即 table.alias()),但 ORM 级别的别名保留了 ORM 映射对象的语义,这对于继承映射、选项和其他场景非常重要。例如:
Friend = aliased(Person)
session.query(Person, Friend).join((Friend, Person.friends)).all()
  • query.join() 大大增强。 - 现在可以以多种方式指定连接的目标和 ON 子句。可以仅提供目标类,SQLA 将尝试通过外键以与 table.join(someothertable) 相同的方式与其形成连接。也可以提供目标和显式的 ON 条件,其中 ON 条件可以是 relation() 名称、实际类描述符或 SQL 表达式。或者仍然可以使用旧的仅 relation() 名称或类描述符的方式。请参阅 ORM 教程,其中有几个示例。
  • 推荐为不需要(也不偏好)表和映射器之间抽象的应用程序使用声明式 - [/docs/05/reference/ext/declarative.html 声明式] 模块,用于将 Tablemapper() 和用户定义的类对象的表达式结合在一起,强烈推荐,因为它简化了应用程序配置,确保了“每个类一个映射器”的模式,并允许对不同的 mapper() 调用可用的完整配置范围。现在将单独使用 mapper()Table 称为“经典 SQLAlchemy 使用”,当然可以与声明式自由混合使用。
  • 已从类中删除 .c. 属性(即 MyClass.c.somecolumn)。与 0.4 版本一样,类级别的属性可用作查询元素,即 Class.c.propname 现在被 Class.propname 取代,c 属性仍然保留在表对象上,其中它们指示表上存在的 Column 对象的命名空间。
    要获取映射类的表(如果您之前没有保留它):
table = class_mapper(someclass).mapped_table
  • 通过列进行迭代:
for col in table.c:
    print(col)
  • 使用特定列:
table.c.somecolumn
  • 类绑定描述符支持完整的列运算符以及文档化的关系导向运算符,如 has()any()contains() 等。
    移除.c.的原因是在 0.5 中,类绑定的描述符可能具有不同的含义,以及关于类映射的信息,与普通的Column对象不同-并且存在一些情况下,您可能希望明确使用其中之一。通常,使用类绑定的描述符会调用一组映射/多态感知的转换,而使用表绑定的列则不会。在  0.4 中,这些转换适用于所有表达式,但是 0.5  完全区分列和映射描述符,仅对后者应用转换。因此,在许多情况下,特别是在处理连接表继承配置以及使用query()时,Class.propnametable.c.colname是不可互换的。
    例如,session.query(users.c.id, users.c.name)session.query(User.id, User.name)是不同的;在后一种情况下,Query知道正在使用的映射器,并且可以使用进一步的映射器特定操作,如query.join()query.with_parent()等,但在前一种情况下则不行。此外,在多态继承场景中,类绑定的描述符指的是多态可选择的列,而不一定是直接对应描述符的表列。例如,一组通过连接表继承到person表的类,每个表的person_id列都将其Class.person_id属性映射到person中的person_id列,而不是其子类表。版本 0.4 会自动将此行为映射到表绑定的Column对象上。在 0.5 中,这种自动转换已被移除,因此实际上可以使用表绑定的列来覆盖多态查询时发生的转换;这使得Query能够在连接表或具体表继承设置中创建优化的选择,以及可移植的子查询等。
  • 会话现在与事务自动同步。 会话现在默认自动与事务同步,包括自动刷新和自动过期。除非使用autocommit选项禁用,否则始终存在事务。当所有三个标志都设置为默认值时,会话在回滚后能够优雅地恢复,并且很难将过时数据输入会话。有关详细信息,请参阅新的会话文档。
  • 隐式排序已移除。这将影响依赖 SA 的“隐式排序”行为的 ORM 用户,该行为规定所有没有order_by()的 Query 对象将按照主映射表的“id”或“oid”列进行排序,并且所有延迟/急切加载的集合都会应用类似的排序。在 0.5 版本中,必须在mapper()relation()对象上明确配置自动排序(如果需要),或者在使用Query时进行配置。
    要将 0.4 映射转换为 0.5,使其排序行为与 0.4 或之前的版本极为相似,请在mapper()relation()上使用order_by设置:
mapper(
    User,
    users,
    properties={"addresses": relation(Address, order_by=addresses.c.id)},
    order_by=users.c.id,
)
  • 要在backref上设置排序,使用backref()函数:
"keywords": relation(
    Keyword,
    secondary=item_keywords,
    order_by=keywords.c.name,
    backref=backref("items", order_by=items.c.id),
)
  • 使用声明式?为了帮助新的order_by要求,现在可以使用稍后在 Python 中评估的字符串来设置order_by和相关内容(这仅适用于声明式,而不是普通映射器):
class MyClass(MyDeclarativeBase):
    ...
    "addresses": relation("Address", order_by="Address.id")
  • 通常在加载基于列表的项目集合的relation()上设置order_by是个好主意,因为否则无法影响排序。除此之外,最佳实践是使用Query.order_by()来控制加载的主要实体的排序。
  • 会话现在是 autoflush=True/autoexpire=True/autocommit=False。 - 要设置它,只需调用sessionmaker()而不带参数。现在transactional=True的名称是autocommit=False。刷新发生在每个查询发出时(使用autoflush=False禁用),在每个commit()之前(一如既往),以及在每个begin_nested()之前(因此回滚到 SAVEPOINT 是有意义的)。在每个commit()和每个rollback()之后,所有对象都会过期。回滚后,待处理对象被清除,删除的对象移回持久状态。这些默认设置非常好地配合在一起,实际上不再需要像clear()这样的旧技术(也更名为expunge_all())。
    注:在rollback()后,会话现在是可重用的。标量和集合属性的更改、添加和删除都会被回滚。
  • session.add()取代 session.save()、session.update()、session.save_or_update()。 - session.add(someitem)session.add_all([list of items])方法取代了save()update()save_or_update()。这些方法将在整个 0.5 版本中继续被弃用。
  • backref 配置更简洁。 - 当前backref()函数在未明确说明时,现在使用前向relation()primaryjoinsecondaryjoin参数。不再需要在两个方向分别指定primaryjoin/secondaryjoin
  • 简化多态选项。 - ORM 的“多态加载”行为已经简化。在 0.4 版本中,mapper()有一个名为polymorphic_fetch的参数,可以配置为selectdeferred。此选项已被移除;现在映射器将仅推迟未在 SELECT 语句中出现的任何列。实际使用的 SELECT 语句由with_polymorphic映射器参数控制(在 0.4 中也有,替换了select_table),以及Query上的with_polymorphic()方法(在 0.4 中也有)。
    对于继承类的延迟加载的改进是,映射器现在在所有情况下都生成“优化”版本的 SELECT 语句;也就是说,如果类 B 从 A 继承,并且在类 B 上已经过期了几个属性,则刷新操作将仅在 SELECT 语句中包含 B 的表,并且不会 JOIN 到 A。
  • Session 上的 execute() 方法将普通字符串转换为 text() 结构,以便可以将绑定参数全部指定为“:bindname”而不需要显式调用 text()。如果需要“原始”SQL,请使用 session.connection().execute("raw text")
  • session.Query().iterate_instances() 已重命名为 instances()。旧的 instances() 方法不再返回列表而是返回迭代器。如果您依赖该行为,则应使用 list(your_query.instances())

扩展 ORM

在 0.5 版本中,我们正在以更多的方式修改和扩展 ORM。以下是摘要:

  • MapperExtension. - 这是经典的扩展类,仍然存在。很少需要的方法是 create_instance()populate_instance()。要控制从数据库加载对象时的初始化,请使用 reconstruct_instance() 方法,或者更容易地使用文档中描述的 @reconstructor 装饰器。
  • SessionExtension. - 这是一个易于使用的会话事件扩展类。特别是,它提供了 before_flush()after_flush()after_flush_postexec() 方法。在许多情况下,推荐使用这种用法而不是 MapperExtension.before_XXX,因为在 before_flush() 中,您可以自由地修改会话的刷新计划,而这在 MapperExtension 中无法做到。
  • AttributeExtension. - 此类现在是公共 API 的一部分,并允许拦截属性上的用户事件,包括属性设置和删除操作以及集合附加和删除操作。它还允许修改要设置或附加的值。在文档中描述的 @validates 装饰器提供了一种快速的方式,可以将任何映射属性标记为特定类方法“验证”的方法。
  • 属性仪器定制。 - 为了完全替换 SQLAlchemy 的属性仪器,或者仅在某些情况下对其进行增强,提供了一个 API。此 API 是为了 Trellis 工具包而制作的,但作为公共 API 提供。在分发目录中的 /examples/custom_attributes 中提供了一些示例。

架构/类型

  • 没有长度的字符串不再生成 TEXT,而是生成 VARCHAR - 当未指定长度时,String 类型不再神奇地转换为 Text 类型。这仅在发出 CREATE TABLE 时才会生效,因为它将发出不带长度参数的 VARCHAR,这在许多(但不是所有)数据库上都是无效的。要创建 TEXT(或 CLOB,即无界限的字符串)列,请使用 Text 类型。
  • PickleType() with mutable=True 需要一个 eq()方法 - PickleType类型在 mutable=True 时需要比较值。使用pickle.dumps()进行比较的方法效率低下且不可靠。如果传入对象没有实现__eq__()并且也不是None,则使用dumps()比较,但会发出警告。对于实现__eq__()的类型,包括所有字典、列表等,比较将使用==,现在默认情况下是可靠的。
  • TypeEngine/TypeDecorator 的 convert_bind_param()和 convert_result_value()方法已移除。 - O’Reilly 书籍不幸地记录了这些方法,尽管它们在 0.3 版本后已被弃用。对于一个继承TypeEngine的用户定义类型,应该使用bind_processor()result_processor()方法进行绑定/结果处理。任何用户定义的类型,无论是扩展TypeEngine还是TypeDecorator,只要使用旧的 0.3 风格,都可以通过以下适配器轻松地适应新风格:
class AdaptOldConvertMethods(object):
  """A mixin which adapts 0.3-style convert_bind_param and
 convert_result_value methods
 """
    def bind_processor(self, dialect):
        def convert(value):
            return self.convert_bind_param(value, dialect)
        return convert
    def result_processor(self, dialect):
        def convert(value):
            return self.convert_result_value(value, dialect)
        return convert
    def convert_result_value(self, value, dialect):
        return value
    def convert_bind_param(self, value, dialect):
        return value
  • 要使用上述 mixin:
class MyType(AdaptOldConvertMethods, TypeEngine): ...
  • ColumnTable上的quote标志以及Table上的quote_schema标志现在控制引号的正面和负面。默认值为None,表示让常规引号规则生效。当为True时,强制引号。当为False时,强制不引号。
  • DEFAULT值 DDL 现在可以更方便地使用Column(..., server_default='val')来指定,废弃了Column(..., PassiveDefault('val'))default=现在专门用于 Python 发起的默认值,并且可以与 server_default 共存。一个新的server_default=FetchedValue()取代了PassiveDefault('')的习惯用法,用于标记受外部触发器影响的列,并且没有 DDL 副作用。
  • SQLite 的DateTimeTimeDate类型现在只接受 datetime 对象,而不是字符串作为绑定参数输入。如果您想创建自己的“混合”类型,接受字符串并将结果返回为日期对象(以您喜欢的任何格式),请创建一个基于StringTypeDecorator。如果您只想要基于字符串的日期,只需使用String
  • 此外,当与 SQLite 一起使用时,DateTimeTime类型现在以与str(datetime)相同的方式表示 Python datetime.datetime对象的“微秒”字段 - 作为分数秒,而不是微秒计数。也就是说:
dt = datetime.datetime(2008, 6, 27, 12, 0, 0, 125)  # 125 usec
# old way
"2008-06-27 12:00:00.125"
# new way
"2008-06-27 12:00:00.000125"
  • 因此,如果现有的基于文件的 SQLite 数据库打算在 0.4 和 0.5 之间使用,您必须将 datetime 列升级为存储新格式(注意:请测试这一点,我相当确定是正确的):
UPDATE  mytable  SET  somedatecol  =
  substr(somedatecol,  0,  19)  ||  '.'  ||  substr((substr(somedatecol,  21,  -1)  /  1000000),  3,  -1);
  • 或者,按如下方式启用“legacy”模式:
from sqlalchemy.databases.sqlite import DateTimeMixin
DateTimeMixin.__legacy_microseconds__ = True

连接池默认不再是线程本地的。

0.4 版本的默认设置pool_threadlocal=True导致意外行为,例如在单个线程中使用多个会话时。在 0.5 中,此标志已关闭。要重新启用 0.4 的行为,请在create_engine()中指定pool_threadlocal=True,或者通过strategy="threadlocal"使用“threadlocal”策略。

*args 被接受,*args 不再被接受

method(\*args) vs. method([args]) 的策略是,如果方法接受代表固定结构的可变长度项目集合,则使用\*args。如果方法接受数据驱动的可变长度项目集合,则使用[args]

  • 各种 Query.options()函数eagerload()eagerload_all()lazyload()contains_eager()defer()undefer()现在都接受可变长度的\*keys作为参数,这允许使用描述符制定路径,例如:
query.options(eagerload_all(User.orders, Order.items, Item.keywords))
  • 为了向后兼容,仍然接受单个数组参数。
  • 类似地,Query.join()Query.outerjoin() 方法接受可变长度的*args,向后兼容仍然接受单个数组:
query.join("orders", "items")
query.join(User.orders, Order.items)
  • in_() 方法现在只接受列表参数,不再接受\*args

已移除

  • entity_name - 这个特性一直存在问题,很少被使用。0.5 更深入地揭示了entity_name存在的问题,因此被移除。如果需要为单个类使用不同的映射,将类拆分为单独的子类并分别映射它们。一个示例在[wiki:UsageRecipes/EntityName]中。有关原因的更多信息请参见  https://groups.google.c  om/group/sqlalchemy/browse_thread/thread/9e23a0641a88b96d? hl=en 。
  • get()/load() 清理
    load() 方法已被移除。其功能有点随意,基本上是从 Hibernate 复制过来的,在那里也不是一个特别有意义的方法。
    要获得等效功能:
x = session.query(SomeClass).populate_existing().get(7)
  • Session.get(cls, id)Session.load(cls, id) 已被移除。Session.get()session.query(cls).get(id) 是冗余的。
    MapperExtension.get() 也被移除(MapperExtension.load()也是)。要重写Query.get()的功能,使用一个子类:
class MyQuery(Query):
    def get(self, ident): ...
session = sessionmaker(query_cls=MyQuery)()
ad1 = session.query(Address).get(1)
  • sqlalchemy.orm.relation()
    下列已弃用的关键字参数已被移除:
    外键,关联,私有,属性扩展,is_backref
    特别是,attributeext 被替换为 extension - AttributeExtension 类现在在公共 API 中。
  • session.Query()
    下列已弃用的函数已被移除:
    列表,标量,count_by,select_whereclause,get_by,select_by,join_by,selectfirst,selectone,select,execute,select_statement,select_text,join_to,join_via,selectfirst_by,selectone_by,apply_max,apply_min,apply_avg,apply_sum
    另外,已移除了join()outerjoin()add_entity()add_column()中的id关键字参数。要将Query中的目标表别名指向结果列,请使用aliased构造:
from sqlalchemy.orm import aliased
address_alias = aliased(Address)
print(session.query(User, address_alias).join((address_alias, User.addresses)).all())
  • sqlalchemy.orm.Mapper
  • instances()
  • get_session() - 此方法可能不太显著,但其效果是将延迟加载与特定会话关联,即使父对象完全分离,当使用scoped_session()或旧的SessionContextExt等扩展时。一些依赖于此行为的应用程序可能不再按预期工作;但好的编程实践是始终确保对象存在于会话中,如果需要从其属性访问数据库。
  • mapper(MyClass, mytable)
    映射类不再使用“c”类属性进行检测;例如MyClass.c
  • sqlalchemy.orm.collections
    _prepare_instrumentation别名已移除。
  • sqlalchemy.orm
    已移除EXT_PASS别名的EXT_CONTINUE
  • sqlalchemy.engine
    DefaultDialect.preexecute_sequences.preexecute_pk_sequences的别名已移除。
    已移除不推荐使用的engine_descriptors()函数。
  • sqlalchemy.ext.activemapper
    模块已移除。
  • sqlalchemy.ext.assignmapper
    模块已移除。
  • sqlalchemy.ext.associationproxy
    在代理的.append(item, \**kw)上的关键字参数传递已移除,现在简单地是.append(item)
  • sqlalchemy.ext.selectresultssqlalchemy.mods.selectresults
    模块已移除。
  • sqlalchemy.ext.declarative
    declared_synonym()已移除。
  • sqlalchemy.ext.sessioncontext
    模块已移除。
  • sqlalchemy.log
    SADeprecationWarning别名到sqlalchemy.exc.SADeprecationWarning的移除。
  • sqlalchemy.exc
    exc.AssertionError已移除,使用替代名称相同的 Python 内置函数。
  • sqlalchemy.databases.mysql
    已移除不推荐使用的get_version_info方言方法。

已更名或移动

  • sqlalchemy.exceptions现在是sqlalchemy.exc
    该模块仍可在 0.6 版本之前使用旧名称导入。
  • FlushErrorConcurrentModificationErrorUnmappedColumnError -> sqlalchemy.orm.exc
    这些异常已移至 orm 包。导入‘sqlalchemy.orm’将在 0.6 版本之前为兼容性安装 sqlalchemy.exc 的别名。
  • sqlalchemy.logging -> sqlalchemy.log
    此内部模块已更名。在打包 SA 与 py2app 等扫描导入工具时不再需要特殊处理。
  • session.Query().iterate_instances() -> session.Query().instances().

已弃用

  • Session.save()Session.update()Session.save_or_update()
    以上三个被Session.add()替代
  • sqlalchemy.PassiveDefault
    使用Column(server_default=...)在底层转换为 sqlalchemy.DefaultClause()。
  • session.Query().iterate_instances()。已更名为instances().
相关文章
|
存储 安全 Linux
OpenSSH之Windows账户访问操作
OpenSSH之Windows账户访问操作
1161 0
|
SQL 存储 测试技术
SqlAlchemy 2.0 中文文档(五十七)(4)
SqlAlchemy 2.0 中文文档(五十七)
411 0
|
存储 自然语言处理 API
打破文本边界:如何进行多模态RAG评估
一般的检索增强生成(RAG,Retrieval-Augmented Generation)方法主要依赖于文本数据,常常忽略了图像中的丰富信息。那么应该如何解决呢?本文带你了解一下这个模型。
打破文本边界:如何进行多模态RAG评估
|
消息中间件 存储 NoSQL
剖析 Redis List 消息队列的三种消费线程模型
Redis 列表(List)是一种简单的字符串列表,它的底层实现是一个双向链表。 生产环境,很多公司都将 Redis 列表应用于轻量级消息队列 。这篇文章,我们聊聊如何使用 List 命令实现消息队列的功能以及剖析消费者线程模型 。
剖析 Redis List 消息队列的三种消费线程模型
|
Docker 容器
docker设置国内镜像源
docker设置国内镜像源
38374 5
|
SQL 缓存 关系型数据库
SqlAlchemy 2.0 中文文档(四十四)(2)
SqlAlchemy 2.0 中文文档(四十四)
232 4
|
SQL 缓存 数据库连接
SqlAlchemy 2.0 中文文档(二十二)(2)
SqlAlchemy 2.0 中文文档(二十二)
279 3
|
SQL 关系型数据库 MySQL
SqlAlchemy 2.0 中文文档(五十七)(1)
SqlAlchemy 2.0 中文文档(五十七)
171 1
|
前端开发 JavaScript
前端模拟接口工具推荐——Apifox(mock数据)【图解教程】
前端模拟接口工具推荐——Apifox(mock数据)【图解教程】
4115 1
|
SQL 缓存 关系型数据库
SqlAlchemy 2.0 中文文档(四十四)(3)
SqlAlchemy 2.0 中文文档(四十四)
334 0