SQLAlchemy 2.0 文档
自动映射¶
定义 sqlalchemy.ext.declarative
系统的扩展,该系统自动从数据库模式生成映射类和关系,通常从反射的模式生成,但并非必须如此。
希望 AutomapBase
系统可以为非常著名的 SQLSoup 所尝试解决的问题提供一个快速且现代化的解决方案,即从现有的数据库动态生成快速且基本的 对象模型。通过严格地在映射器配置级别解决问题,并与现有的声明式类技术完全集成,AutomapBase
旨在为快速自动生成临时映射的问题提供一种良好集成的解决方案。
提示
自动映射 扩展面向“零声明”方法,其中完整的 ORM 模型(包括类和预先命名的关系)可以从数据库模式动态生成。对于仍希望使用显式类声明(包括显式关系定义)以及与表反射结合使用的应用程序,DeferredReflection
类(在 使用 DeferredReflection 中描述)是更好的选择。
基本用法¶
最简单的用法是将现有数据库反映到新模型中。我们以类似于创建声明式基类的方式创建一个新的 AutomapBase
类,使用 automap_base()
。然后,我们调用 AutomapBase.prepare()
方法,要求它反映模式并生成映射
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import Session
from sqlalchemy import create_engine
Base = automap_base()
# engine, suppose it has two tables 'user' and 'address' set up
engine = create_engine("sqlite:///mydatabase.db")
# reflect the tables
Base.prepare(autoload_with=engine)
# mapped classes are now created with names by default
# matching that of the table name.
User = Base.classes.user
Address = Base.classes.address
session = Session(engine)
# rudimentary relationships are produced
session.add(Address(email_address="[email protected]", user=User(name="foo")))
session.commit()
# collection-based relationships are by default named
# "<classname>_collection"
u1 = session.query(User).first()
print(u1.address_collection)
在上面,调用 AutomapBase.prepare()
方法并传递 AutomapBase.prepare.reflect
参数表示 MetaData.reflect()
方法将被调用到这个声明式基类的 MetaData
集合中;然后,MetaData
中的每个可用 Table
将自动生成一个新的映射类。连接各个表的 ForeignKeyConstraint
对象将用于在类之间生成新的双向 relationship()
对象。类和关系遵循我们可以自定义的默认命名方案。此时,我们的基本映射(由相关的 User
和 Address
类组成)已准备好以传统方式使用。
注意
可用意味着为了映射一个表,它必须指定一个主键。此外,如果检测到该表是两个其他表之间的纯关联表,则它将不会被直接映射,而是被配置为这两个引用表映射之间的多对多表。
从现有元数据生成映射¶
我们可以将预先声明的 MetaData
对象传递给 automap_base()
。此对象可以以任何方式构造,包括以编程方式、从序列化文件或通过使用 MetaData.reflect()
方法进行反射。下面,我们演示了反射和显式表声明的组合
from sqlalchemy import create_engine, MetaData, Table, Column, ForeignKey
from sqlalchemy.ext.automap import automap_base
engine = create_engine("sqlite:///mydatabase.db")
# produce our own MetaData object
metadata = MetaData()
# we can reflect it ourselves from a database, using options
# such as 'only' to limit what tables we look at...
metadata.reflect(engine, only=["user", "address"])
# ... or just define our own Table objects with it (or combine both)
Table(
"user_order",
metadata,
Column("id", Integer, primary_key=True),
Column("user_id", ForeignKey("user.id")),
)
# we can then produce a set of mappings from this MetaData.
Base = automap_base(metadata=metadata)
# calling prepare() just sets up mapped classes and relationships.
Base.prepare()
# mapped classes are ready
User = Base.classes.user
Address = Base.classes.address
Order = Base.classes.user_order
从多个模式生成映射¶
AutomapBase.prepare()
方法在与反射一起使用时,最多只能一次从一个模式中反射表,使用 AutomapBase.prepare.schema
参数来指示要从中反射的模式名称。为了使用来自多个模式的表来填充 AutomapBase
,可以多次调用 AutomapBase.prepare()
方法,每次调用时都将不同的名称传递给 AutomapBase.prepare.schema
参数。 AutomapBase.prepare()
方法会维护一个已映射 Table
对象的内部列表,并且只为自上次运行 AutomapBase.prepare()
以来新增的 Table
对象添加新的映射
e = create_engine("postgresql://scott:tiger@localhost/test")
Base.metadata.create_all(e)
Base = automap_base()
Base.prepare(e)
Base.prepare(e, schema="test_schema")
Base.prepare(e, schema="test_schema_2")
版本 2.0 中的新内容: AutomapBase.prepare()
方法可以被调用任意次数;每次运行时,只为新添加的表进行映射。在 1.4 及更早版本中,多次调用会导致错误,因为它会尝试重新映射已映射的类。以前使用 MetaData.reflect()
直接调用的解决方法仍然可以使用。
跨多个模式自动映射同名表¶
对于多个模式可能具有相同名称的表,因此将生成相同名称的类的情况,可以通过使用 AutomapBase.prepare.classname_for_table
钩子以基于每个模式应用不同的类名,或者使用 AutomapBase.prepare.modulename_for_table
钩子来解决冲突,该钩子允许通过更改其有效的 __module__
属性来消除相同名称的类的歧义。在下面的示例中,此钩子用于为所有类创建 __module__
属性,其格式为 mymodule.<schemaname>
,其中,如果不存在模式,则使用模式名称 default
e = create_engine("postgresql://scott:tiger@localhost/test")
Base.metadata.create_all(e)
def module_name_for_table(cls, tablename, table):
if table.schema is not None:
return f"mymodule.{table.schema}"
else:
return f"mymodule.default"
Base = automap_base()
Base.prepare(e, modulename_for_table=module_name_for_table)
Base.prepare(e, schema="test_schema", modulename_for_table=module_name_for_table)
Base.prepare(e, schema="test_schema_2", modulename_for_table=module_name_for_table)
相同名称的类被组织成一个层次结构集合,可从 AutomapBase.by_module
获取。使用特定包/模块的点分隔名称遍历此集合,直到到达所需的类名。
注意
当使用 AutomapBase.prepare.modulename_for_table
钩子返回一个新的 __module__
(它不是 None
)时,该类**不会**被放置到 AutomapBase.classes
集合中;只有没有显式模块名的类会被放置在这里,因为该集合不能单独表示相同名称的类。
在上面的示例中,如果数据库在所有三个默认模式、test_schema
模式和 test_schema_2
模式中包含名为 accounts
的表,那么三个独立的类将可用为
Base.by_module.mymodule.default.accounts
Base.by_module.mymodule.test_schema.accounts
Base.by_module.mymodule.test_schema_2.accounts
为所有 AutomapBase
类生成的默认模块命名空间是 sqlalchemy.ext.automap
。如果没有使用 AutomapBase.prepare.modulename_for_table
钩子,则 AutomapBase.by_module
的内容将完全在 sqlalchemy.ext.automap
命名空间内(例如 MyBase.by_module.sqlalchemy.ext.automap.<classname>
),它将包含与在 AutomapBase.classes
中看到的一系列相同的类。因此,通常只需要在存在显式 __module__
约定时才使用 AutomapBase.by_module
。
显式指定类¶
提示
如果希望在应用程序中突出显示显式类,请考虑使用 DeferredReflection
。
automap
扩展允许以类似于 DeferredReflection
类的方式显式定义类。从 AutomapBase
扩展的类就像常规的声明性类,但它们在构造后不会立即被映射,而是在我们调用 AutomapBase.prepare()
时被映射。 AutomapBase.prepare()
方法将根据我们使用的表名使用我们已建立的类。如果我们的模式包含表 user
和 address
,我们可以定义一个或两个类来使用
from sqlalchemy.ext.automap import automap_base
from sqlalchemy import create_engine
# automap base
Base = automap_base()
# pre-declare User for the 'user' table
class User(Base):
__tablename__ = "user"
# override schema elements like Columns
user_name = Column("name", String)
# override relationships too, if desired.
# we must use the same name that automap would use for the
# relationship, and also must refer to the class name that automap will
# generate for "address"
address_collection = relationship("address", collection_class=set)
# reflect
engine = create_engine("sqlite:///mydatabase.db")
Base.prepare(autoload_with=engine)
# we still have Address generated from the tablename "address",
# but User is the same as Base.classes.User now
Address = Base.classes.address
u1 = session.query(User).first()
print(u1.address_collection)
# the backref is still there:
a1 = session.query(Address).first()
print(a1.user)
上面,一个更复杂的细节是,我们说明了覆盖 relationship()
对象之一,而 automap 会创建这些对象。要做到这一点,我们需要确保名称与 automap 通常生成的名称匹配,因为关系名将是 User.address_collection
,并且从 automap 的角度来看,引用的类的名称称为 address
,即使我们在使用此类时将其称为 Address
。
覆盖命名方案¶
automap
的任务是基于模式生成映射的类和关系名,这意味着它在确定这些名称的方式方面有决策点。这三个决策点是使用可以传递给 AutomapBase.prepare()
方法的函数提供的,被称为 classname_for_table()
、name_for_scalar_relationship()
和 name_for_collection_relationship()
。任何或所有这些函数都像下面的示例一样提供,其中我们使用“驼峰式”方案来命名类,并使用 Inflect 包来命名集合的“复数形式”
import re
import inflect
def camelize_classname(base, tablename, table):
"Produce a 'camelized' class name, e.g."
"'words_and_underscores' -> 'WordsAndUnderscores'"
return str(
tablename[0].upper()
+ re.sub(
r"_([a-z])",
lambda m: m.group(1).upper(),
tablename[1:],
)
)
_pluralizer = inflect.engine()
def pluralize_collection(base, local_cls, referred_cls, constraint):
"Produce an 'uncamelized', 'pluralized' class name, e.g."
"'SomeTerm' -> 'some_terms'"
referred_name = referred_cls.__name__
uncamelized = re.sub(
r"[A-Z]",
lambda m: "_%s" % m.group(0).lower(),
referred_name,
)[1:]
pluralized = _pluralizer.plural(uncamelized)
return pluralized
from sqlalchemy.ext.automap import automap_base
Base = automap_base()
engine = create_engine("sqlite:///mydatabase.db")
Base.prepare(
autoload_with=engine,
classname_for_table=camelize_classname,
name_for_collection_relationship=pluralize_collection,
)
从上面的映射中,我们现在将有类 User
和 Address
,其中,从 User
到 Address
的集合被称为 User.addresses
User, Address = Base.classes.User, Base.classes.Address
u1 = User(addresses=[Address(email="[email protected]")])
关系检测¶
automap 完成的大部分工作是基于外键生成 relationship()
结构。以下是此机制针对多对一和一对多关系的工作原理
一个给定的
Table
(已知映射到特定类)将被检查是否有ForeignKeyConstraint
对象。对于每个
ForeignKeyConstraint
,存在的远程Table
对象将与要映射到它的类(如果有)匹配,否则将被跳过。由于我们正在检查的
ForeignKeyConstraint
对应于从立即映射的类到该类的引用,因此关系将被设置为多对一,引用该类;一个对应的多对一反向引用将被创建到该类上,引用该类。如果
ForeignKeyConstraint
中的任何列不可为空(例如nullable=False
),则relationship.cascade
关键字参数将被设置为all, delete-orphan
,并将被添加到要传递给关系或反向引用的关键字参数中。如果ForeignKeyConstraint
报告ForeignKeyConstraint.ondelete
被设置为CASCADE
(对于非空值)或SET NULL
(对于可为空的列集),则选项relationship.passive_deletes
标志被设置为True
,作为关系关键字参数集的一部分。请注意,并非所有后端都支持反射 ON DELETE。关系的名称是使用
AutomapBase.prepare.name_for_scalar_relationship
和AutomapBase.prepare.name_for_collection_relationship
可调用函数来确定的。需要注意的是,默认的关系命名是从**实际的类名**派生名称的。如果您为特定类声明了显式名称,或者指定了其他类命名方案,那么将从该名称派生关系名称。会检查这些类是否具有匹配这些名称的现有映射属性。如果在一侧检测到一个,但在另一侧没有检测到,则
AutomapBase
会尝试在缺失的一侧创建一个关系,然后使用relationship.back_populates
参数将新的关系指向另一侧。在通常情况下,如果两侧都没有关系,则
AutomapBase.prepare()
会在“多对一”侧生成一个relationship()
,并使用relationship.backref
参数将其与另一侧匹配。relationship()
(以及可选的backref()
)的生成将交给AutomapBase.prepare.generate_relationship
函数,该函数可以由最终用户提供,以增强传递给relationship()
或backref()
的参数,或者使用这些函数的自定义实现。
自定义关系参数¶
AutomapBase.prepare.generate_relationship
钩子可用于向关系添加参数。在大多数情况下,我们可以使用现有的 generate_relationship()
函数来返回对象,在将我们自己的参数添加到给定的关键字字典后。
以下是将 relationship.cascade
和 relationship.passive_deletes
选项发送到所有一对多关系的说明。
from sqlalchemy.ext.automap import generate_relationship
from sqlalchemy.orm import interfaces
def _gen_relationship(
base, direction, return_fn, attrname, local_cls, referred_cls, **kw
):
if direction is interfaces.ONETOMANY:
kw["cascade"] = "all, delete-orphan"
kw["passive_deletes"] = True
# make use of the built-in function to actually return
# the result.
return generate_relationship(
base, direction, return_fn, attrname, local_cls, referred_cls, **kw
)
from sqlalchemy.ext.automap import automap_base
from sqlalchemy import create_engine
# automap base
Base = automap_base()
engine = create_engine("sqlite:///mydatabase.db")
Base.prepare(autoload_with=engine, generate_relationship=_gen_relationship)
多对多关系¶
automap
会生成多对多关系,例如那些包含 secondary
参数的关系。生成这些关系的过程如下
在分配任何映射类之前,会检查给定的
Table
是否包含ForeignKeyConstraint
对象。如果该表包含两个且仅包含两个
ForeignKeyConstraint
对象,并且该表中的所有列都是这两个ForeignKeyConstraint
对象的成员,则该表被假定为“辅助”表,并且**不会直接映射**。Table
所引用的两个(或一个,对于自引用)外部表将与将被映射到它们的类匹配(如果有)。如果找到了两侧的映射类,则会在这两个类之间创建一个双向多对多
relationship()
/backref()
对。多对多的覆盖逻辑与一对多/多对一的覆盖逻辑相同;将调用
generate_relationship()
函数来生成结构,并将维护现有属性。
具有继承的关系¶
automap
不会生成任何在继承关系中的两个类之间的关系。也就是说,给定以下两个类
class Employee(Base):
__tablename__ = "employee"
id = Column(Integer, primary_key=True)
type = Column(String(50))
__mapper_args__ = {
"polymorphic_identity": "employee",
"polymorphic_on": type,
}
class Engineer(Employee):
__tablename__ = "engineer"
id = Column(Integer, ForeignKey("employee.id"), primary_key=True)
__mapper_args__ = {
"polymorphic_identity": "engineer",
}
来自 Engineer
到 Employee
的外键不用于关系,而是用于建立这两个类之间的连接继承。
请注意,这意味着 automap 不会为从子类到超类的外键生成任何关系。如果映射具有从子类到超类的实际关系,那么这些关系需要明确指定。在下文中,由于我们从 Engineer
到 Employee
有两个单独的外键,因此我们需要同时设置我们想要的关系以及 inherit_condition
,因为这些不是 SQLAlchemy 可以猜测的内容。
class Employee(Base):
__tablename__ = "employee"
id = Column(Integer, primary_key=True)
type = Column(String(50))
__mapper_args__ = {
"polymorphic_identity": "employee",
"polymorphic_on": type,
}
class Engineer(Employee):
__tablename__ = "engineer"
id = Column(Integer, ForeignKey("employee.id"), primary_key=True)
favorite_employee_id = Column(Integer, ForeignKey("employee.id"))
favorite_employee = relationship(Employee, foreign_keys=favorite_employee_id)
__mapper_args__ = {
"polymorphic_identity": "engineer",
"inherit_condition": id == Employee.id,
}
处理简单的命名冲突¶
在映射期间发生命名冲突的情况下,请根据需要覆盖 classname_for_table()
、name_for_scalar_relationship()
和 name_for_collection_relationship()
。例如,如果 automap 尝试将多对一关系命名为与现有列相同的名称,则可以选择其他约定。给定一个模式
CREATE TABLE table_a (
id INTEGER PRIMARY KEY
);
CREATE TABLE table_b (
id INTEGER PRIMARY KEY,
table_a INTEGER,
FOREIGN KEY(table_a) REFERENCES table_a(id)
);
上面的模式将首先将 table_a
表自动映射为名为 table_a
的类;然后,它将在该类上自动映射一个指向 table_b
的关系,其名称与该相关类相同,例如 table_a
。此关系名称与映射列 table_b.table_a
冲突,并且会在映射时发出错误。
我们可以通过使用下划线来解决此冲突,如下所示
def name_for_scalar_relationship(base, local_cls, referred_cls, constraint):
name = referred_cls.__name__.lower()
local_table = local_cls.__table__
if name in local_table.columns:
newname = name + "_"
warnings.warn("Already detected name %s present. using %s" % (name, newname))
return newname
return name
Base.prepare(
autoload_with=engine,
name_for_scalar_relationship=name_for_scalar_relationship,
)
或者,我们可以在列端更改名称。可以使用在 显式命名声明性映射列 中描述的技术来修改映射的列,方法是将列显式分配给新名称
Base = automap_base()
class TableB(Base):
__tablename__ = "table_b"
_table_a = Column("table_a", ForeignKey("table_a.id"))
Base.prepare(autoload_with=engine)
将 Automap 与显式声明一起使用¶
如前所述,automap 不依赖于反射,并且可以使用 Table
对象的任何集合,这些对象位于 MetaData
集合中。由此可以得出,automap 也可以用于生成缺失的关系,前提是给定一个完整定义了表元数据的完整模型。
from sqlalchemy.ext.automap import automap_base
from sqlalchemy import Column, Integer, String, ForeignKey
Base = automap_base()
class User(Base):
__tablename__ = "user"
id = Column(Integer, primary_key=True)
name = Column(String)
class Address(Base):
__tablename__ = "address"
id = Column(Integer, primary_key=True)
email = Column(String)
user_id = Column(ForeignKey("user.id"))
# produce relationships
Base.prepare()
# mapping is complete, with "address_collection" and
# "user" relationships
a1 = Address(email="u1")
a2 = Address(email="u2")
u1 = User(address_collection=[a1, a2])
assert a1.user is u1
在上面,给定基本完整的 User
和 Address
映射,我们在 Address.user_id
上定义的 ForeignKey
允许在映射的类上生成双向关系对 Address.user
和 User.address_collection
。
请注意,当子类化 AutomapBase
时,需要 AutomapBase.prepare()
方法;如果没有调用该方法,那么我们声明的类将处于未映射状态。
拦截列定义¶
的 MetaData
和 Table
对象支持一个事件钩子 DDLEvents.column_reflect()
,它可用于在构建 Column
对象之前拦截关于数据库列的反映信息。例如,如果我们想使用 "attr_<columnname>"
这样的命名约定来映射列,则可以应用该事件,如下所示
@event.listens_for(Base.metadata, "column_reflect")
def column_reflect(inspector, table, column_info):
# set column.key = "attr_<lower_case_name>"
column_info["key"] = "attr_%s" % column_info["name"].lower()
# run reflection
Base.prepare(autoload_with=engine)
版本 1.4.0b2 新版功能: 的 DDLEvents.column_reflect()
事件可以应用于 MetaData
对象。
API 参考¶
对象名称 | 描述 |
---|---|
automap_base([declarative_base], **kw) |
生成一个声明性自动映射基类。 |
“自动映射”架构的基类。 |
|
classname_for_table(base, tablename, table) |
返回应使用的类名,给出表的名称。 |
generate_relationship(base, direction, return_fn, attrname, ..., **kw) |
为两个映射类生成 |
name_for_collection_relationship(base, local_cls, referred_cls, constraint) |
返回用于从一个类引用另一个类的属性名,用于集合引用。 |
name_for_scalar_relationship(base, local_cls, referred_cls, constraint) |
返回用于从一个类引用另一个类的属性名,用于标量对象引用。 |
- function sqlalchemy.ext.automap.automap_base(declarative_base: Type[Any] | None = None, **kw: Any) → Any¶
生成一个声明性自动映射基类。
此函数生成一个新的基类,它是
AutomapBase
类以及由declarative_base()
生成的声明性基类的产物。除了
declarative_base
之外的所有参数都是关键字参数,它们将直接传递给declarative_base()
函数。
- class sqlalchemy.ext.automap.AutomapBase¶
“自动映射”架构的基类。
的
AutomapBase
类可以与由declarative_base()
函数生成的“声明性基类”类进行比较。在实践中,AutomapBase
类始终与实际的声明性基类一起用作 mixin。通常使用
automap_base()
函数实例化新的可子类化AutomapBase
。另请参阅
-
attribute
sqlalchemy.ext.automap.AutomapBase.
by_module: ClassVar[ByModuleProperties]¶ 一个
Properties
实例,它包含一个分层结构的点分隔模块名称,这些名称链接到类。此集合是
AutomapBase.classes
集合的替代方案,在使用AutomapBase.prepare.modulename_for_table
参数时很有用,该参数将对生成的类应用不同的__module__
属性。自动映射生成的类的默认
__module__
为sqlalchemy.ext.automap
;要使用AutomapBase.by_module
访问此命名空间,如下所示User = Base.by_module.sqlalchemy.ext.automap.User
如果一个类的
__module__
为mymodule.account
,访问此命名空间如下所示MyClass = Base.by_module.mymodule.account.MyClass
版本 2.0 新版功能。
另请参阅
-
attribute
sqlalchemy.ext.automap.AutomapBase.
classes: ClassVar[Properties[Type[Any]]]¶ 一个包含类的
Properties
实例。此对象的行为与表的
.c
集合非常类似。类在给定的名称下存在,例如Base = automap_base() Base.prepare(autoload_with=some_engine) User, Address = Base.classes.User, Base.classes.Address
对于与
Properties
的方法名称重叠的类名,例如items()
,还支持 getitem 形式Item = Base.classes["items"]
-
attribute
sqlalchemy.ext.automap.AutomapBase.
metadata: ClassVar[MetaData]¶ 引用将用于新的
Table
对象的MetaData
集合。另请参阅
-
classmethod
sqlalchemy.ext.automap.AutomapBase.
prepare(autoload_with: Engine | None = None, engine: Any | None = None, reflect: bool = False, schema: str | None = None, classname_for_table: PythonNameForTableType | None = None, modulename_for_table: PythonNameForTableType | None = None, collection_class: Any | None = None, name_for_scalar_relationship: NameForScalarRelationshipType | None = None, name_for_collection_relationship: NameForCollectionRelationshipType | None = None, generate_relationship: GenerateRelationshipType | None = None, reflection_options: Dict[_KT, _VT] | immutabledict[_KT, _VT] = {}) → None¶ 从
MetaData
中提取映射类和关系并执行映射。有关完整文档和示例,请参见 基本用法。
- 参数:
autoload_with¶ – 一个
Engine
或Connection
,用于执行模式反射; 当指定此参数时,MetaData.reflect()
方法将在此方法的范围内被调用。engine¶ –
遗留; 使用
AutomapBase.autoload_with
。用于指示Engine
或Connection
,用于反射表,如果AutomapBase.reflect
为 True。已弃用,从版本 1.4 起:参数
AutomapBase.prepare.engine
已弃用,将在未来版本中移除。请使用参数AutomapBase.prepare.autoload_with
。reflect¶ –
遗留; 使用
AutomapBase.autoload_with
。指示是否应该调用MetaData.reflect()
。已弃用,从版本 1.4 起:参数
AutomapBase.prepare.reflect
已弃用,将在未来版本中移除。当传递AutomapBase.prepare.autoload_with
时,将启用反射。classname_for_table¶ – 可调用函数,用于生成新类名,给定表名。默认为
classname_for_table()
。modulename_for_table¶ –
可调用函数,用于生成内部生成的类的有效
__module__
,以允许在单个自动映射基类中存在多个同名类,这些类位于不同的“模块”中。默认为
None
,表示不会显式设置__module__
; Python 运行时将使用值sqlalchemy.ext.automap
用于这些类。当将
__module__
分配给生成的类时,可以使用AutomapBase.by_module
集合,根据点分隔的模块名访问它们。使用此钩子显式分配了__module_
的类,不会被放置到AutomapBase.classes
集合中,只会放置到AutomapBase.by_module
中。版本 2.0 新版功能。
另请参阅
name_for_scalar_relationship¶ – 可调用函数,用于生成标量关系的关系名。默认为
name_for_scalar_relationship()
。name_for_collection_relationship¶ – 可调用函数,用于生成面向集合的关系的关系名。默认为
name_for_collection_relationship()
。generate_relationship¶ – 可调用函数,用于实际生成
relationship()
和backref()
结构。默认为generate_relationship()
。collection_class¶ – 当创建一个新的
relationship()
对象来表示集合时,将使用的 Python 集合类。默认值为list
。schema¶ –
使用
AutomapBase.prepare.autoload_with
参数反射表时要反射的模式名称。该名称被传递给MetaData.reflect.schema
参数MetaData.reflect()
。省略时,使用数据库连接使用的默认模式。注意
该
AutomapBase.prepare.schema
参数支持一次反射单个模式。为了包含来自多个模式的表,请对AutomapBase.prepare()
进行多次调用。有关包括使用附加命名约定来解决表名冲突的多模式自动映射的概述,请参阅部分 从多个模式生成映射。
在版本 2.0 中新增:
AutomapBase.prepare()
支持直接调用任意次数,跟踪已经处理过的表,以避免再次处理它们。reflection_options¶ –
如果存在,此选项字典将被传递给
MetaData.reflect()
,以提供一般反射特定选项,例如only
和/或特定于方言的选项,例如oracle_resolve_synonyms
。在版本 1.4 中新增。
-
attribute
- function sqlalchemy.ext.automap.classname_for_table(base: Type[Any], tablename: str, table: Table) → str¶
返回应使用的类名,给出表的名称。
默认实现是
return str(tablename)
可以使用
AutomapBase.prepare.classname_for_table
参数指定备用实现。
- function sqlalchemy.ext.automap.name_for_scalar_relationship(base: Type[Any], local_cls: Type[Any], referred_cls: Type[Any], constraint: ForeignKeyConstraint) → str¶
返回用于从一个类引用另一个类的属性名,用于标量对象引用。
默认实现是
return referred_cls.__name__.lower()
可以使用
AutomapBase.prepare.name_for_scalar_relationship
参数指定备用实现。- 参数:
base¶ – 进行准备的
AutomapBase
类。local_cls¶ – 要在本地端映射的类。
referred_cls¶ – 要在引用端映射的类。
constraint¶ – 正在检查以生成此关系的
ForeignKeyConstraint
。
- function sqlalchemy.ext.automap.name_for_collection_relationship(base: Type[Any], local_cls: Type[Any], referred_cls: Type[Any], constraint: ForeignKeyConstraint) → str¶
返回用于从一个类引用另一个类的属性名,用于集合引用。
默认实现是
return referred_cls.__name__.lower() + "_collection"
可以使用
AutomapBase.prepare.name_for_collection_relationship
参数指定备用实现。- 参数:
base¶ – 进行准备的
AutomapBase
类。local_cls¶ – 要在本地端映射的类。
referred_cls¶ – 要在引用端映射的类。
constraint¶ – 正在检查以生成此关系的
ForeignKeyConstraint
。
- 函数 sqlalchemy.ext.automap.generate_relationship(base: Type[Any], direction: RelationshipDirection, return_fn: Callable[..., Relationship[Any]] | Callable[..., ORMBackrefArgument], attrname: str, local_cls: Type[Any], referred_cls: Type[Any], **kw: Any) → Relationship[Any] | ORMBackrefArgument¶
为两个映射类生成
relationship()
或backref()
。可以使用
AutomapBase.prepare.generate_relationship
参数指定此函数的替代实现。此函数的默认实现如下所示
if return_fn is backref: return return_fn(attrname, **kw) elif return_fn is relationship: return return_fn(referred_cls, **kw) else: raise TypeError("Unknown relationship function: %s" % return_fn)
- 参数:
base¶ – 进行准备的
AutomapBase
类。direction¶ – 指示关系的“方向”;这将是
ONETOMANY
、MANYTOONE
、MANYTOMANY
之一。return_fn¶ – 用于创建关系的默认函数。这将是
relationship()
或backref()
。backref()
函数的结果将用于在第二步生成一个新的relationship()
,因此,如果使用自定义关系函数,则用户定义的实现必须正确区分这两个函数。attrname¶ – 将此关系分配到的属性名称。如果
generate_relationship.return_fn
的值为backref()
函数,则此名称是分配给反向引用者的名称。local_cls¶ – 此关系或反向引用者在本地存在的“本地”类。
referred_cls¶ – 此关系或反向引用者引用的“被引用”类。
**kw¶ – 所有附加的关键字参数都将传递给该函数。
- 返回值:
由
generate_relationship.return_fn
参数决定的relationship()
或backref()
结构。
flambé! 龙和 炼金术士 图像设计由 Rotem Yaari 创建并慷慨捐赠。
使用 Sphinx 7.2.6 创建。 文档最后生成时间:2024 年 11 月 8 日星期五 上午 8:41:19 EST