SQLAlchemy ORM Query Guide 前置环境_plain_setup.rst映射与夹具数据全解【免费下载链接】sqlalchemyThe Database Toolkit for Python项目地址: https://gitcode.com/gh_mirrors/sq/sqlalchemy导读doc/build/orm/queryguide/_plain_setup.rst是 SQLAlchemy ORM 官方 Query Guide 中所有 SELECT 查询示例的公共底座它用声明式Declarative风格一次性定义好User、Address、Order、Item四张映射表及关联关系再通过内存 SQLite 引擎与五条海绵宝宝宇宙夹具数据为后续select.rst、columns.rst、relationships.rst等文档提供可直接复现的实验环境。读完本文你将掌握这套夹具的完整模型设计、双向关系与多对多关联的配置方法、Session绑定连接的初始化流程并了解如何把同一套映射迁移到你自己的 ORM 查询调试场景中。该文档在整个 Query Guide 中的定位_plain_setup.rst以:orphan:指令开头说明它不会出现在文档目录toctree导航中属于典型的被引用页。它服务于 ORM Querying Guide 下的多份正文文档Writing SELECT statements for ORM Mapped Classes 在开头的 About this Document 提示中直接引用该页:doc:View the ORM setup for this page _plain_setup并声明其映射源自 unified_tutorial 的tutorial_declaring_mapped_classes一节ORM-Enabled INSERT, UPDATE, and DELETE statements 则通过.. doctest-include _dml_setup.rst引入另一份稍有不同的夹具_dml_setup.rstColumn Loading 对应的则是带Book模型的_deferred_setup.rstRelationship Loading Techniques 同样声明大多数示例假设使用与_plain_setup相似的 User/Address 映射。因此本文档是理解select.rst中select(User)、select(User, Address).join(User.addresses)、Bundle、aliased等全部示例执行结果的数据前提。文档中的所有提示符代码都是 doctest 形式可直接粘贴到交互式 Python 中验证。模型设计的四个核心问题1. 声明式基类Base(DeclarativeBase)from sqlalchemy.orm import DeclarativeBase class Base(DeclarativeBase): passDeclarativeBase在源码中定义于 lib/sqlalchemy/orm/decl_api.py其 docstring 明确指出它是declarative class definitions 使用的基类并配合DeclarativeAttributeIntercept元类工作。所有映射类只需继承Base即可自动获得__table__Table对象、metadataMetaData容器等基础设施无需再手工声明__metadata__或重复配置Column的细节。2.User与Address经典一对多双向关系from typing import List, Optional from sqlalchemy import Column, create_engine, ForeignKey, Table from sqlalchemy.orm import Mapped, mapped_column, relationship, Session class User(Base): __tablename__ user_account id: Mapped[int] mapped_column(primary_keyTrue) name: Mapped[str] fullname: Mapped[Optional[str]] addresses: Mapped[List[Address]] relationship(back_populatesuser) orders: Mapped[List[Order]] relationship() def __repr__(self) - str: return fUser(id{self.id!r}, name{self.name!r}, fullname{self.fullname!r}) class Address(Base): __tablename__ address id: Mapped[int] mapped_column(primary_keyTrue) user_id: Mapped[int] mapped_column(ForeignKey(user_account.id)) email_address: Mapped[str] user: Mapped[User] relationship(back_populatesaddresses) def __repr__(self) - str: return fAddress(id{self.id!r}, email_address{self.email_address!r})几个值得注意的设计决策类型注解驱动列定义Mapped[int]与mapped_column()搭配时SQL 类型Integer与可空性Optional[str]→NULL允许都会从注解推导。源码 lib/sqlalchemy/orm/_orm_constructors.py 中mapped_column的 docstring 明确说明nullable省略时非主键列默认允许 NULL、主键列默认 NOT NULL类型可由注解、或由ForeignKey指向列的类型推导。back_populates建立双向关系User.addresses ↔ Address.user是一对多双向关系的标准写法两侧必须互相指定back_populates否则声明式映射在配置阶段会抛出ArgumentError提示缺少反向引用。外键字符串引用ForeignKey(user_account.id)使用表名.列名字符串形式这正是声明式映射的常见写法——字符串在Base.metadata全部注册完成后由 mapper 配置阶段解析。__repr__自定义输出两个类都定义了__repr__这直接决定了后续select(User)示例中打印出来的结果形态例如User(id1, namespongebob, fullnameSpongebob Squarepants)。User.addresses使用类型提示Mapped[List[Address]]中的字符串前向引用允许在Address类尚未定义时就写出该注解。3.Order与Item通过关联表实现多对多order_items_table Table( order_items, Base.metadata, Column(order_id, ForeignKey(user_order.id), primary_keyTrue), Column(item_id, ForeignKey(item.id), primary_keyTrue), ) class Order(Base): __tablename__ user_order id: Mapped[int] mapped_column(primary_keyTrue) user_id: Mapped[int] mapped_column(ForeignKey(user_account.id)) items: Mapped[List[Item]] relationship(secondaryorder_items_table) class Item(Base): __tablename__ item id: Mapped[int] mapped_column(primary_keyTrue) name: Mapped[str] description: Mapped[str]这里展示了声明式映射与经典 Core 映射的混用关联表使用 CoreTable显式构造order_items是一张纯关联表两个复合主键分别外键到user_order.id与item.id。它被挂到Base.metadata上因此Base.metadata.create_all(engine)会连同它一起建表。relationship(secondary...)表达多对多Order.items通过secondary参数指向该关联表。从源码 lib/sqlalchemy/orm/_orm_constructors.py 中relationship的函数签名可以看到secondary是第二个位置参数用于提供父类与子类之间的关联表当该参数存在时关系即被解释为多对多。仅单向声明Order.items定义了多对多但没有对应的Item.orders反向关系——这在 SQLAlchemy 中完全合法反向加载路径会由 ORM 自动按需建立User.orders同样只是单向的一对多关系。注意表名Order映射到user_order表而非order这是为了规避ORDER作为 SQL 保留字带来的建表与查询问题Item则映射到item表。引擎、元数据与 Session从建表到事务的完整初始化engine create_engine(sqlitepysqlite:///:memory:, echoTrue) Base.metadata.create_all(engine) conn engine.connect() session Session(conn)这段初始化代码是整份夹具的启动开关每一行都有明确的职责create_engine(sqlitepysqlite:///:memory:, echoTrue)创建指向内存 SQLite 数据库的引擎。pysqlite表示使用 Python 标准库自带的sqlite3驱动:memory:表示数据库完全驻留内存进程退出即消失非常适合文档演示与单元测试。echoTrue会打开 SQL 语句日志让后续示例中SELECT ... FROM user_account等语句原样打印。Base.metadata.create_all(engine)根据Base.metadata中注册的全部表user_account、address、user_order、item、order_items在引擎上执行CREATE TABLE。文档注释显示此处会输出BEGIN ...表示 DDL 也在事务中执行。conn engine.connect()显式取得一个连接。这里的关键点在于——文档刻意把连接从引擎中取出再交给Session。session Session(conn)将Session绑定到该连接而非引擎。这样后续所有查询都复用一个物理连接适合教学场景的连贯演示。若直接写Session(engine)每次事务结束连接会被归还连接池:memory:数据库内容在新连接上不可见。完成映射定义与建表后文档即进入夹具数据写入阶段通过session.add_all([...])批量提交 5 个User对象及其嵌套的Address列表随后session.commit()提交事务文档注释BEGIN ... COMMIT最后conn.begin()重新开启一个事务为后续select.rst中的查询示例准备就绪的会话状态。夹具数据五条记录与六条地址_plain_setup.rst插入的数据全部取自《海绵宝宝》角色命名这种风格与 unified_tutorial、tutorial data_select 一脉相承使select.rst中数十个示例的输出具备可读性与一致性。完整数据如下User.idnamefullnameaddressesemail_address1spongebobSpongebob Squarepantsspongebobsqlalchemy.org2sandySandy Cheekssandysqlalchemy.org、squirrelsquirrelpower.org3patrickPatrick Starpat999aol.com4squidwardSquidward Tentaclesstentclsqlalchemy.org5ehkrabsEugene H. Krabs无地址数据特点对后续查询语义影响深远一个用户有多条地址sandy 有 2 条使join、group_by等查询产生有意义的多行结果select.rst中select(User, Address).join(User.addresses).order_by(User.id, Address.id)的输出正好是 5 行spongebob 1 行、sandy 2 行、patrick 1 行、squidward 1 行。ehkrabs 没有地址是 inner join 会被过滤、而 outer join / left join 会保留的天然测试样本。两个用户共用sqlalchemy.org域名spongebob、squidward为func.count、group_by(email)之类的聚合演示提供了重复值素材。order_items表与Order、Item在本夹具中只建表、不插数据——文档只定义模型结构为select.rst的关联与多实体查询示例预留 schema但不产生额外噪音数据。文档在仓库中的关联与印证同源教学体系unified_tutorial 的Using SELECT Statements一节同样使用user_account、spongebob等命名但用的是user_tableCoreTable与声明式User两种风格_plain_setup.rst则把声明式风格独立抽成 Query Guide 的公共前置二者互为印证。Query Guide 内部引用链select.rst 的所有select()示例都建立在本文档数据之上其About this Document提示与 relationships.rst 开头的说明共同指向_plain_setupdml.rst 与 columns.rst 则各自维护_dml_setup.rst与_deferred_setup.rst形成一套 Query Guide、多份前置夹具的文档组织模式。源码层面的印证lib/sqlalchemy/orm/_orm_constructors.py 中mapped_column的签名与 docstring 证实了注解推导类型与可空性primary_key默认 Falsenullable默认值规则等行为lib/sqlalchemy/orm/_orm_constructors.py 中relationship的签名证实secondary、back_populates、uselist、lazy默认select等参数的作用lib/sqlalchemy/orm/decl_api.py 中DeclarativeBase的定义表明其配合DeclarativeAttributeIntercept元类拦截并处理类属性仓库测试夹具 test/orm/_fixtures.py 中的User/Address/Order/Item映射含order_items关联表、secondaryorder_items的items关系、addresses的backrefuser与文档映射高度同构证明该模型组合是 ORM 测试与文档共同验证过的经典配置。将本夹具用于你自己的查询调试把_plain_setup.rst的代码作为可复现的实验起点只需三步即可用于自己的项目按需裁剪模型保留Base、User、Address三件套即可覆盖绝大多数一对多查询实验需要多对多时再加入Order/Item与order_items关联表。保持连接级 Session的初始化顺序务必使用conn engine.connect()Session(conn)的组合或改用sqlite:///你的文件.db磁盘数据库否则内存库数据会在事务结束后蒸发。替换夹具数据把session.add_all中的 5 个用户换成你的业务数据保持有人无地址有人多条地址这类边界样本能让 join、聚合、分组类查询的验证更充分。小结_plain_setup.rst虽然只是一份不起眼的前置设置页却是整个 ORM Query Guide 查询示例的事实基础它以声明式映射完整呈现了一对多User.addresses、多对多Order.items、复合主键关联表order_items三类最常用的映射形态并通过内存 SQLite 连接级Session保证了文档示例的可复现性。理解这份夹具等于同时掌握了 SQLAlchemy 2.x 声明式映射的核心配置面与查询示例的数据语义是深入阅读 select.rst 之前最值得花时间的一步。【免费下载链接】sqlalchemyThe Database Toolkit for Python项目地址: https://gitcode.com/gh_mirrors/sq/sqlalchemy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
