自动映射


定义 sqlalchemy.ext.declarative 系统的扩展,该系统会自动从数据库架构生成映射的类和关系,通常但不一定是反映的类和关系。


希望 AutomapBase 系统提供一个快速的 和现代化解决方案解决了非常著名的 SQLSoup 还尝试解决生成快速而基本对象的问题 模型。 通过严格解决问题 在 Mapper 配置级别,并与现有的 声明式类技术,AutomapBase 旨在为方便自动生成 ad-hoc 映射的问题提供一种集成良好的方法。


提示


Automap 扩展面向 “零声明” 方法,其中可以从数据库模式动态生成包含类和预命名关系的完整 ORM 模型。对于仍希望使用显式类声明(包括显式关系定义)并结合表反射的应用程序,DeferredReflection 类,如 使用 DeferredReflection 是更好的选择。


基本用法


最简单的用法是将现有数据库反映到新模型中。我们以类似于使用 automap_base() 创建声明式基类的方式创建新的 AutomapBase 类。然后,我们在生成的基类上调用 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="foo@bar.com", 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() method 将在此声明性基上调用 类的 MetaData 集合;然后,MetaData 中的每个 Table 将获得一个新的 Map 类 自动生成。 ForeignKeyConstraint 对象 将各个表链接在一起将用于生成新的、双向的 relationship() 对象。类和关系遵循我们可以自定义的默认命名方案。此时,由相关 UserAddress 类组成的基本映射已经可以以传统方式使用了。


注意


我们所说的 viable 是指要映射的表必须指定主键。此外,如果检测到该表是其他两个表之间的纯关联表,则不会直接映射该表,而是将其配置为两个引用表的映射之间的多对多表。


从现有元数据生成映射


我们可以将预先声明的 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


从多个 Schema 生成映射


AutomapBase.prepare() 方法与反射一起使用时可能会反射 表中,使用 AutomapBase.prepare.schema 参数来指示要从中反映的架构的名称。为了填充 AutomapBase 对于来自多个 schema 的表,可以调用 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() 也仍然可用。


跨多个 schema 自动映射同名表


对于多个架构可能具有相同名称的表并因此生成相同名称的类的常见情况,可以通过使用 AutomapBase.prepare.classname_for_table hook 来解决冲突 基于每个 schema 应用不同的类名,或者使用 AutomapBase.prepare.modulename_for_table hook 的 intent 语句,它允许通过更改同名类的有效__module__来消除同名类的歧义 属性。在下面的示例中,此钩子用于创建 __module__ 属性,其格式为 mymodule.<schemaname>,其中,如果不存在 schema,则使用 schema name 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 hook 返回一个不是 None 的新__module__,则该类为 放入 AutomapBase.classes 集合中;只有没有被赋予显式 moduleName 的类才会被放置在这里,因为该集合不能单独表示同名的类。


在上面的示例中,如果数据库在所有三个默认架构中都包含一个名为 accounts 的表,则 test_schema 架构和 test_schema_2架构,将提供三个单独的类:

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 hook 一起使用,AutomapBase.by_module的内容将完全在 sqlalchemy.ext.automap 命名空间(例如 MyBase.by_module.sqlalchemy.ext.automap.<classname> ),其中包含 与 在 AutomapBase.classesAutomapBase.by_module 当存在显式 __module__ 约定时。


显式指定类


提示


如果预期显式类在应用程序中突出显示,请考虑改用 DeferredReflection


automap 扩展允许以类似于 DeferredReflection 类的方式显式定义类。从 AutomapBase 扩展而来的类的行为类似于常规的声明性类,但在构造后不会立即映射,而是在我们调用 AutomapBase.prepare() 时进行映射。 这 AutomapBase.prepare() 方法将利用我们已有的类 根据我们使用的表名建立。 如果 schema 包含表 useraddress 中,我们可以定义一个或两个要使用的类:

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)


上面,一个更复杂的细节是,我们演示了如何覆盖 automap 本来会创建的 relationship() 对象之一。 为此,我们需要确保名称与自动映射匹配 通常会生成,因为关系名称将为 User.address_collection,从自动映射的角度来看,所引用的类的名称称为 address,即使我们在使用此类时将其称为 Address


覆盖命名方案


AutoMap 的任务是根据架构生成映射的类和关系名称,这意味着它在如何确定这些名称方面具有决策点。这三个决策点是使用可以传递给 AutomapBase.prepare() 方法的函数提供的,称为 classname_for_table()。 name_for_scalar_relationship() name_for_collection_relationship() . 任何或所有这些 函数如下例所示,其中我们使用 “Camel Case” scheme 用于类名,并使用 “pluralizer” 用于集合名称 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,
)


从上面的映射中,我们现在将有 UserAddress 类,其中从 UserAddress 的集合被调用 User.addresses 中:

User, Address = Base.classes.User, Base.classes.Address

u1 = User(addresses=[Address(email="foo@bar.com")])


关系检测


automap 完成的绝大多数工作是生成 relationship() 结构。适用于多对一和一对多关系的机制如下:


  1. 检查已知映射到特定类的给定 Table 中是否有 ForeignKeyConstraint 对象。


  2. 在每个 ForeignKeyConstraint 中,远程 桌子 object present 与它要映射到的类匹配, 如果有,否则跳过。


  3. 作为 ForeignKeyConstraint 我们正在检查对应于一个 引用,则将建立关系 作为多对一引用引用的类;相应的 一对多 backref 将在引用的 class 上创建 添加到此类。


  4. 如果属于 ForeignKeyConstraint 的 不可为 null(例如 nullable=False),则 relationship.cascade 关键字参数delete-orphan 将被添加到关键字参数中 传递给 relationship 或 backref。 如果 ForeignKeyConstraint 报告说 ForeignKeyConstraint.ondelete 对于非 null 设置为 CASCADE,对于可为空的列集设置为 SET NULL,则选项 relationship.passive_deletes flag 在关系关键字参数集中设置为 True。请注意,并非所有后端都支持 ON DELETE 的反射。


  5. 关系的名称是使用 AutomapBase.prepare.name_for_scalar_relationship AutomapBase.prepare.name_for_collection_relationship 可调用函数。 请务必注意,默认关系 naming 从实际的类名派生名称。如果您通过声明特定类为其指定了显式名称,或者指定了备用类命名方案,则该名称将派生自该名称。


  6. 检查类中是否存在与这些匹配的现有 Map 属性 名字。 如果在一侧检测到一个,但在另一侧没有检测到, AutomapBase 尝试在缺失的一侧创建关系,然后使用 relationship.back_populates 参数,以便 将新关系指向另一端。


  7. 在双方都没有关系的通常情况下, AutomapBase.prepare() “many-to-one” 端,并使用 relationship.backref 参数。


  8. relationship() 的生成和可选的 backref() 将传递给 AutomapBase.prepare.generate_relationship 功能,该功能可由最终用户提供,以便增强 传递给 relationship()backref() 的参数,或者使用这些函数的自定义实现。


自定义关系参数


AutomapBase.prepare.generate_relationship 子可用于向关系添加参数。在大多数情况下,我们可以利用现有的 generate_relationship() 函数来返回对象,然后用我们自己的参数扩充给定的关键字字典。


以下是如何发送 relationship.cascaderelationship.passive_deletes options 以及所有一对多关系:

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 将生成多对多关系,例如那些包含辅助参数的关系。生产这些的过程如下:


  1. 检查给定的 Table ForeignKeyConstraint 的 对象,然后再为其分配任何映射的类。


  2. 如果表包含 2 和 2 ForeignKeyConstraint 的 对象,并且此表中的所有列都是这两个 ForeignKeyConstraint 对象,该表被假定为“辅助”表,不会直接映射


  3. 两个(或一个,对于自引用)外部表,其中 桌子 引用与它们将要匹配的类 mapped(如果有)。


  4. 如果定位了两侧的映射类,则多对多双向 relationship() / backref() pair 在两者之间创建 类。


  5. 多对多的覆盖逻辑与 1 对多/多对 1 的覆盖逻辑相同;调用 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",
    }


EngineerEmployee 的外键不用于关系,而是用于在两个类之间建立联接继承。


请注意,这意味着 automap 不会为从子类链接到超类的外键生成任何关系。如果 Map 也具有从 subclass 到 superclass 的实际关系,那么这些关系需要是明确的。下面,由于我们有两个单独的外键,从 EngineerEmployee,我们需要设置我们想要的关系以及 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)
);


上面的 schema 首先将 table_a 表自动映射为名为 table_a;然后,它会将 RELATIONSHIP 自动映射到 table_b 类 替换为与此相关类相同的名称,例如 table_a。此关系名称与 mapping 列 table_b.table_a 冲突,并在 mapping 时发出错误。


我们可以通过使用下划线来解决此冲突,如下所示:

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 不依赖于反射,并且可以使用 元数据 收集。 由此,也可以使用 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


在上面,给定基本完整的 UserAddress 映射, 我们在 Address.user_id ForeignKey 上定义的 ForeignKey 允许双向关系对 Address.userUser.address_collection 映射的类上生成。


请注意,当子类化 AutomapBase 时,需要 AutomapBase.prepare() 方法;如果未调用,则我们声明的类处于 un-mapped 状态。


拦截列定义


MetaDataTable 对象支持事件钩子 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)


生成声明性自动映射基。

AutomapBase


“automap” 架构的基类。


classname_for_table(base, tablename, table)


返回应使用的类名(给定表的名称)。


generate_relationship(base, direction, 方向, return_fn, attrname, ..., **kw)


生成 relationship()backref() 代表两个 映射类。


name_for_collection_relationship(基础、local_cls、referred_cls、约束)


返回应该用于从一个类引用到另一个类的属性名称,以便进行集合引用。


name_for_scalar_relationship(基础、local_cls、referred_cls、约束)


返回应该用于从一个类引用到另一个类的属性名称,用于标量对象引用。


函数 sqlalchemy.ext.automap 中。automap_basedeclarative_base:Type[Any]None=None, **kw Any Any


生成声明性自动映射基。


此函数生成一个新的基类,该基类是 AutomapBase 类以及由 declarative_base() 中。


declarative_base 之外的所有参数都是直接传递给 declarative_base() 的关键字参数 功能。


参数

  • declarative_base —— 由 declarative_base() 中。当 this 被传递时,该函数不再调用 declarative_base() 本身,并且所有其他关键字参数都将被忽略。


  • **kw —— 关键字参数被传递给 declarative_base() 中。


sqlalchemy.ext.automap 中。AutomapBase


“automap” 架构的基类。


AutomapBase 类可以与 declarative_base() 生成的“声明性基”类进行比较 功能。 在实践中,AutomapBase 类总是与实际的声明性基类一起用作 mixin。


新的可子类化 AutomapBase 通常使用 automap_base() 函数进行实例化。


另请参阅


自动映射


属性 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 版的新Function。


属性 sqlalchemy.ext.automap.AutomapBase. ClassVar[Properties[Type[Any]]]¶


包含类的 Properties 实例。


此对象的行为与表上的 .c 集合非常相似。类以给定的名称存在,例如:

Base = automap_base()
Base.prepare(autoload_with=some_engine)

User, Address = Base.classes.User, Base.classes.Address


对于与方法名称 属性,例如 items(),还支持 getitem 表单:

Item = Base.classes["items"]

属性 sqlalchemy.ext.automap.AutomapBase. 元数据 ClassVar[MetaData]


引用将用于新 Table 对象的 MetaData 集合。


另请参阅


访问表和元数据


类方法 sqlalchemy.ext.automap.AutomapBase. prepareautoload_with:EngineNone=None, engine:AnyNone=None, reflect bool = False, schema:strNone=None, classname_for_table:PythonNameForTableTypeNone=None, modulename_for_table:PythonNameForTableTypeNone=None, collection_class:AnyNone=无, name_for_scalar_relationship:NameForScalarRelationshipTypeNone=无, name_for_collection_relationship:NameForCollectionRelationshipTypeNone=无, generate_relationship:GenerateRelationshipTypeNone=无, reflection_options:Dict[_KT,_VT]immutabledict[_KT,_VT]={}


MetaData 并执行映射。


有关完整文档和示例,请参阅 基本用途


参数

函数 sqlalchemy.ext.automap 中。classname_for_tablebase Type[Any]tablename strtable Table str 的¶


返回应使用的类名(给定表的名称)。


默认实现为:

return str(tablename)


可以使用 AutomapBase.prepare.classname_for_table 参数。


参数

结果


字符串类名。


注意


在 Python 2 中,用于类名的字符串必须是非 Unicode 对象,例如 str() 对象。Table.name 属性通常是 Python unicode 子类 所以 str() 函数应该在考虑任何非 ASCII 字符之后应用于此名称。


函数 sqlalchemy.ext.automap 中。name_for_scalar_relationshipbase 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 —— 执行 prepare 的 AutomapBase 类。


  • local_cls —— 要在本地端映射的类。


  • referred_cls – 要在引用端映射的类。


  • constraint—— 正在检查以产生此关系的 ForeignKeyConstraint


函数 sqlalchemy.ext.automap 中。name_for_collection_relationshipbase 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 —— 执行 prepare 的 AutomapBase 类。


  • local_cls —— 要在本地端映射的类。


  • referred_cls – 要在引用端映射的类。


  • constraint—— 正在检查以产生此关系的 ForeignKeyConstraint


函数 sqlalchemy.ext.automap 中。generate_relationshipbase Type[Any]direction RelationshipDirection, return_fn:Callable[...,Relationship[Any]]Callable[...,ORMBackrefArgument], attrname strlocal_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 —— 执行 prepare 的 AutomapBase 类。


  • direction—— 表示关系的 “direction”;这将是 ONETOMANY、MANYTOONE、MANYTOMANY 之一。


  • return_fn – 默认用于创建关系的函数。这将是 relationship()backref()backref() 函数的结果将用于在第二步中生成新的 relationship(),因此,如果使用自定义关系函数,用户定义的实现正确区分这两个函数至关重要。


  • attrName – 此关系被分配到的属性名称。如果 的 generate_relationship.return_fn 值为 backref() 函数,则此名称是分配给 backref 的名称。


  • local_cls – 此关系或 backref 将本地存在的 “local” 类。


  • referred_cls – 关系或 backref 引用的 “referred” 类。


  • **kw—— 所有其他关键字参数都传递给函数。


结果


relationship()backref() 结构,由 generate_relationship.return_fn 参数指示。