SQLAlchemy 0.1 Changelog 深度解读:2006 年诞生初期 ORM、类型系统与多方言架构的关键演进

发布时间:2026/9/23 12:18:34
SQLAlchemy 0.1 Changelog 深度解读:2006 年诞生初期 ORM、类型系统与多方言架构的关键演进 SQLAlchemy 0.1 Changelog 深度解读2006 年诞生初期 ORM、类型系统与多方言架构的关键演进【免费下载链接】sqlalchemyThe Database Toolkit for Python项目地址: https://gitcode.com/gh_mirrors/sq/sqlalchemySQLAlchemy 的doc/build/changelog/changelog_01.rst记录了 0.1.1 至 0.1.7 共七个版本的完整变更历史覆盖 2006 年 2 月至 5 月期间项目从原型走向可用的核心演进Mapper/Query 重构、Session 与 Unit of Work 的定型、类型系统两次重构、version_id 乐观锁与 post_update 等至今仍在使用的重要特性以及 Postgres、Oracle、MySQL、SQLite、MS-SQL 多方言适配。读完本文你将理解 SQLAlchemy 现代架构的起源脉络并能在当前仓库lib/sqlalchemy中逐一对照这些特性的源码级实现。版本总览与阅读方法版本发布日期主题定位0.1.12006-02-23属性/关系/EagerLoading 基础修复0.1.22006-02-24schema 递归调用性能修复0.1.32006-03-02post_update、mapper.using、sql 与 schema 解耦0.1.42006-03-13类型系统重构、convert_unicode、Oracle 反射0.1.52006-03-27SQLSession 嵌套事务、version_id、entity_name0.1.62006-04-12Query 对象分离、mods 插件系统、MS-SQL 支持0.1.72006-05-05拓扑排序修复、DISTINCT ON、多项 bug 修复所有变更均以.. change::指令记录参见 doc/build/changelog/README.txt 中的格式规范:tags:与:tickets:可逗号分隔多个元素正文使用 reStructuredText/Sphinx 标记。这是 SQLAlchemy 历史上最早期的一批 changelog直接反映了 0.1 系列先跑起来、再持续重构的演进风格——多条记录都带有再次修复仍然没修好这类坦诚的注释例如 0.1.7 中types types types! 仍然没修好……只好再次使用 TypeDecorator。Session 与 Unit of Work现代 ORM 工作单元模型的定型0.1.5 与 0.1.6 是两个决定性版本它们把 SQLAlchemy 的 ORM 会话模型逐步塑造成今天的样子。0.1.5嵌套事务与 session 生命周期SQLSession 概念0.1.5 在 SQLEngine 上引入 SQLSession负责从连接池获取连接并跟踪进行中的事务引擎新增push_session()/pop_session()允许在既有连接上嵌套打开第二个连接从而支持嵌套事务。Session.nest_onobjectstore.Session新增nest_on参数单个或一组 SQLEngine当该 Session 变为活动会话时自动执行push_session()/pop_session()让工作单元 Session 无需显式调用即可享受嵌套事务。职责拆分0.1.5 将 objectstore 与 unitofwork 分离Session 作用域管理与UoW 提交重活解耦objectstore.Session.refresh(*obj)无条件从数据库重载对象属性expunge()则彻底把对象移出当前 Session。0.1.6 的 flush 化Session 重构后官方保存对象的方式统一为flush()旧的 begin/commit 行为被归入 LegacySession作为 0.2 之前的默认行为。0.1.6 同时把 Mapper 的查询能力抽离成独立的、以 Session 为中心的 Query 对象显著提升mapper.using(session)的性能。0.1.5version_id 乐观并发控制0.1.5 为 mapper 新增version_id关键字参数引用一张 Integer最好非空的 Column用于在映射表上跟踪版本号。每次保存操作递增该数字并把该值写入 UPDATE/DELETE 的条件中参与返回行数统计若返回行数不符则抛出 ConcurrencyError。这一机制完整保留至今当前 mapper.py 中version_id_col的文档依然如此描述检测到 UPDATE 未命中最后已知版本号时抛出StaleDataError。默认生成器为lambda x: (x or 0) 1mapper.py传入False则关闭客户端版本号生成改由服务端触发器维护。继承场景下子类 mapper 会继承父类的version_id_col与version_id_generator若显式指定不一致的列会得到警告mapper.py。0.1.5entity_name 多实体映射同一版本新增entity_name关键字mapper 通过类对象 可选字符串 entity_name默认 None与类关联可为同一个类创建任意多个主 mapper各实体在身份映射identity map中保持彼此独立的身份各自的加载/保存操作都经由自己 entity_name 限定的 mapper 完成。这是同一张表映射多个角色场景的最早期解法。post_update 与关系持久化解决循环依赖的两阶段更新0.1.1 首次加入实验性标志use_update关系由第二条 UPDATE 语句处理——在主 INSERT 之后、主 DELETE 之前执行用于处理循环行依赖。0.1.3 正式完成该特性并定名为post_update在 INSERT 前追加第二条 UPDATE、在 DELETE 后追加第二条 UPDATE从而在不建立依赖关系的前提下调和两个互相依赖的行。该参数在当代 relationships.py 中依然是relationship()的正式参数0.1.1 记录中必须使用显式 aliases的旧时代早已被 0.1.1 同版本的 EagerLoading 全面内部化所取代eager loading 在 0.1.1 起就一律使用别名alias进行查询复杂的 eager load 链不再需要任何显式别名指令。类型系统的两次重构与 PickleType 的诞生类型系统在 0.1 系列经历了两次方向相反的重构0.1.4 第一次重构采用更简单的继承模式让任意通用类型都可被直接子类化不再需要 TypeDecorator。0.1.7 打脸回退重构后类型仍然没修好又不得不回到 TypeDecorator 方案。这段波折在今天留下了清晰的痕迹现代 PickleType 正是TypeDecorator的子类而 TypeDecorator 本身已成为 SQLAlchemy 类型定制的基础设施。同期的类型相关变更还包括0.1.4 引入convert_unicodeFalse引擎参数让所有 String 类型执行 Unicode 编解码让 String 表现得像 Unicode配套encodingutf8参数用于 Unicode 类型以及convert_unicodeTrue时 String 的所有编解码调用。0.1.6 将类型系统绑定时机从schema 构建时推迟到查询编译时简化了类型系统与 ProxyEngine。0.1.7 修复convert_unicodeTrue时反射reflection失败的问题MySQL binary 类型把数组输出转换为 buffer从而修复 PickleType。0.1.1 修复 psycopg1 日期/时间与 None 的兼容问题0.1.5 为 SQLite 增加绑定参数日期转换使 pysqlite1 下日期可用。方言支持版图Postgres、Oracle、MySQL、SQLite、MS-SQL0.1 系列已经形成多数据库方言的雏形现代实现在 lib/sqlalchemy/dialectsPostgreSQL0.1.7 为 Postgres 增加 DISTINCT ON 支持用法是distinct[col1, col2, ...]0.1.3 维护 ANSI 函数白名单无参函数调用不输出括号0.1.1 围绕Postgres 不再提供 lastrowid、OID 已废弃展开大量修复——主键列上的数据库侧默认值反射为 PassiveDefault会被显式预执行以便获知刚插入的主键值。Oracle0.1.4 加入由 Andrija Zaric 贡献的表反射复合主键/字典选择仍有遗留 bug0.1.5 反射改用ALL_*视图而非USER_*以获得更大范围并修复外键反射ticket 105同时有 Oracle8 兼容的use_ansi标志把 JOIN 转成()比较与 LIMIT/OFFSET 的反复调整。MySQL0.1.4 修正 MySQL4 自定义表引擎的TYPE而非ENGINE语法并新增 Double、TinyInt0.1.7 修复 binary 类型输出为 buffer 的问题0.1.1 修复日期类型把 timedelta 转为 datetime.time。SQLite0.1.4 修复 LIMIT/OFFSET 语法0.1.5 增加绑定参数日期转换。MS-SQL0.1.6 由 Rick Morrison、Runar Petursson 贡献支持。0.1.4 还签入了初始的 Firebird 模块awaiting testing即等待测试。SQL 表达式层的成型0.1 系列奠定了 SQL 表达式层的基础能力函数与运算符0.1.4 规定 ANSI 标准函数如 current_timestamp不输出括号、其余函数均带括号SQL 函数支持独立execute()/scalar()且接受engine关键字参数0.1.5 支持多段函数名如schema.mypkg.func()0.1.7 增加%运算符__mod__与 CAST 运算符调整并把函数名 LOCAL_TIME/LOCAL_TIMESTAMP 修正为标准的 LOCALTIME/LOCALTIMESTAMP。子查询与列子句0.1.4 支持以scalarTrue标志把 SELECT 语句嵌入列子句0.1.5 改进子查询的 FROM 子句构造0.1.7 修复 INSERT/UPDATE 中子查询的括号问题与 ORDER BY/HAVING 的编译顺序。构造能力0.1.4 的sql.ClauseParameters作为compiled.get_params()的结果对绑定参数做延迟类型处理0.1.1 修复engine.execute_compiled创建后被丢弃的第二个 ResultProxy0.1.1 规定一个 Column 只能属于一张表现已是断言。绑定参数命名0.1.5 修复列标签与绑定参数的两个 bug——绑定参数键名改为由列 label 生成以适配超长名称规则并处理与tablename_colname命名冲突的列。Mapper 与继承体系继承与多态是 0.1 系列反复打磨的主题0.1.3 大规模修复使用继承的 mapper关系针对该 mapper 的本地表而非继承来的表建立使组合模式能配合 lazy/eager loading 工作支持父子 mapper 共用同一张表在两者上指定相同 table 即可。0.1.4 再次重构 EagerLoading 与继承 mapper 的组合eager load 能正确推导别名查询针对继承 mapper 建立的关系会 JOIN 到该 mapper 专属的表可用自定义 primary/secondary join 覆盖。0.1.7 中order_bymapper 属性可被继承 mapper 继承修复 mapper UPDATES/DELETEs 时使用的列类型支持通过关联表实现表到自身的多对多关系。0.1.3 的translate_row相关能力服务于 polymorphic 示例0.1.4 增强了对 UNION 的映射支持并新增 polymorph.py 示例。0.1.5 的MapperExtension.populate_instance()允许扩展参与对象属性填充甚至可调用另一 mapper 的populate_instance()实现属性填充的代理与行转换。0.1.7 新增construct_new标志用__new__而非__init__创建实例0.2 成为标准。0.1.4 的 J.Ellis patch 使selectone()在查询返回多行时抛异常、selectfirst()不抛并新增selectfirst_by与get_by同义和selectone_by。0.1.4 新增setattr_clean/append_clean到 SmartProperty设置属性时不触发 dirty 事件或历史记录。引擎、连接池与默认值处理0.1.4 通用化 create_engine 参数host/hostname、db/dbname/database、password/passwd 等在所有引擎连接上通用让引擎 URI 更通用。0.1.7 中create_engine改用cgi.parse_qsl解析查询字符串0.2 中被弃用。当前入口 create.py 仍保持create_engine(url, **kwargs)的统一形态。0.1.3 sql/schema 解耦sql 包可完全独立运行不依赖引擎即可生成 SELECT/INSERT基于新的 TableClause/ColumnClause 词法对象schema 的 Table/Column 是其物理子类。这大幅简化了 schema/sql 关系移除了 0.1.1 中被诟病的整套getattr()行为并显著提速。schema 拓扑结构正是由 util/topological.py 的依赖排序算法支撑该模块 0.1.7 仍被称为拓扑排序算法的修复对象。连接池0.1.5 新增unique_connection()方法返回不属于线程本地上下文或当前事务的连接invalidate()从池中移除坏连接当时引擎尚缺自动重连。0.1.7 修复 schema 名导致的强制引擎连接问题。默认值0.1.4 为 Column 增加onupdate参数0.1.7 修复列默认值覆盖 INSERT 对象 VALUES 子句的 bug。0.1.4 改进 mapper 使用列默认值的支持从语句执行前的绑定参数中取回预执行默认值填充对象属性若触发了 PassiveDefaults 则改为从数据库回取该行。工作单元与持久化的细节修复拓扑排序0.1.7 修复拓扑排序算法。该算法今日仍在 util/topological.py 的sort()/sort_as_subsets()中用于依赖排序并由 test/base/test_dependency.py 的test_sort_*、test_raise_on_cycle_*等用例持续守护。0.1.5 修复对象提交后未加载的 lazy list 被清空的属性 bug0.1.7 修复 attributes.py 的内存泄漏once and for all并修复懒加载对以外比较运算符、以及 JOIN 条件中两处比较指向同一列时的支持。0.1.7 为 HistoryArraySet 增加extend()方法。0.1.1 两阶段 objectstore.commitbegin/commit返回事务对象 SessionTrans明确事务边界。0.1.5 的 ResultProxy 增加迭代器接口for row in result: ...engine.transaction(func)支持*args, **kwargs透传方便编写事务化装饰器。扩展生态mods、SelectResults、SQLSoup、ActiveMapper0.1.5 与 0.1.6 是扩展生态的起步0.1.5 加入 J. Ellis 的 SQLSoup 模块扩展包0.1.6 跟进其最新版。0.1.6 引入 mods 系统通过install_mods(*modnames)安装可插拔模块来修改/增强核心功能首个 mod 是 SelectResults它修改 mapper 的 select 行为把范围切片转换为 LIMIT/OFFSET 查询作者 Jonas Borgström。0.1.7 补交了漏掉的 selectresults.py。0.1.6 ActiveMapper来自 TG 社区具备初步的继承支持0.1.4 起已支持多对多关系。其他值得注意的变更0.1.7 的单元测试按各数据库支持能力进行资格筛选——这正是现代 test 目录中requirements与方言 suite 机制test/suite、testing/requirements.py的最早雏形。0.1.4 增强日志带时间戳与可配置的格式化系统。0.1.3 的 Index 对象完整实现可独立构造或通过 Column 的index/unique参数创建。0.1.3 提供模块级默认引擎ProxyEngine可用global_connect连接表可在不指定引擎时创建。0.1.5 的get_session().invalidate(*obj)让实例在下次属性访问时自动 refresh。0.1.6 修复 backrefs 的若干问题0.1.4 新增backref()函数支持向反向引用传递关键字参数。0.1.6 为 Select 对象新增for_update标志。0.1.7 的 mapper 增加always_refresh标志0.1.5 引入强制刷新从数据库取回对象的全部属性覆盖任何改动。0.1.2 修复 schema 中的递归调用——该调用此前会递归 994 次后才正常返回没破坏任何东西但拖慢了所有东西由 jpellerin 发现。0.1.6 文档页面基本切换为 Markdown 语法0.1.5 对单元工作Unit of Work文档做了大改。结语从 changelog_01 看 SQLAlchemy 的长寿基因changelog_01.rst虽是 20 年前的记录却浓缩了 SQLAlchemy 最核心的设计决策Query 与 Session 的分离、UoW 与 Session 作用域解耦、类型系统与引擎绑定时机的后移、sql 与 schema 的层次解耦、以别名统一 eager loading、version_id乐观锁与post_update解决循环依赖、以及每版都修不完的类型系统。这些特性大多以几乎相同的形式保留到今天对照 lib/sqlalchemy/orm、lib/sqlalchemy/sql、lib/sqlalchemy/engine 即可逐一验证。阅读 0.1 系列 changelog实际上是在阅读 SQLAlchemy 现代架构的设计说明书。【免费下载链接】sqlalchemyThe Database Toolkit for Python项目地址: https://gitcode.com/gh_mirrors/sq/sqlalchemy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考