Release: 1.4.25 | Release Date: September 22, 2021

SQLAlchemy 1.4 Documentation

映射表列

的默认行为 mapper() 在映射的 Table 到映射的对象属性中,每个属性都根据列本身的名称命名(特别是 key 属性 Column )这种行为可以通过几种方式进行修改。

从属性名称清楚地命名列

默认情况下,映射与 Column 与映射属性的相同-具体来说,它与 Column.key 属性对 Column ,默认与 Column.name .

指定给映射到的python属性的名称 Column 可以不同于 Column.nameColumn.key 正如我们在声明性映射中所演示的那样,只需按这种方式分配:

class User(Base):
    __tablename__ = 'user'
    id = Column('user_id', Integer, primary_key=True)
    name = Column('user_name', String(50))

在哪里 User.id 解析为名为的列 user_idUser.name 解析为名为的列 user_name .

映射到现有表时, Column 对象可以直接引用::

class User(Base):
    __table__ = user_table
    id = user_table.c.user_id
    name = user_table.c.user_name

一个 imperative 映射是将所需的键放在 mapper.properties 带所需键的字典:

mapper_registry.map_imperatively(User, user_table, properties={
   'id': user_table.c.user_id,
   'name': user_table.c.user_name,
})

在下一节中,我们将检查 .key 更紧密。

从反射表自动化列命名方案

在上一节中 从属性名称清楚地命名列 我们展示了 Column 显式映射到类的属性名不能与列的属性名不同。但是如果我们不上市呢 Column 对象,而不是自动生成 Table 使用反射的对象(如中所述 反映数据库对象 )?在这种情况下,我们可以利用 DDLEvents.column_reflect() 阻止生产的事件 Column 对象并为它们提供 Column.key 我们的选择。事件最容易与 MetaData 对象,例如下面我们使用一个链接到 declarative_base 实例:

@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()

对于上述事件,反映了 Column 对象将被截获,我们的事件将添加一个新的“.key”元素,如在下面的映射中:

class MyClass(Base):
    __table__ = Table("some_table", Base.metadata,
                autoload_with=some_engine)

该方法也适用于 自动程序 扩展。参见章节 截取列定义 背景。

用前缀命名所有列

一种快速的列名称前缀方法,通常在映射到现有列名称时使用。 Table 对象,将使用 column_prefix ::

class User(Base):
    __table__ = user_table
    __mapper_args__ = {'column_prefix':'_'}

上面将放置属性名称,例如 _user_id_user_name_password 地图上的等 User 班级。

这种方法在现代用法中不常见。对于处理反射表,更灵活的方法是使用 从反射表自动化列命名方案 .

对列级别选项使用列属性

映射时可以指定选项 Column 使用 column_property() 功能。此函数显式创建 ColumnProperty 用于 mapper() 跟踪 Column 正常情况下 mapper() 自动创建。使用 column_property() ,我们可以传递有关如何 Column 要映射。下面,我们传递一个选项 active_history ,它指定对此列值的更改应首先加载前一个值::

from sqlalchemy.orm import column_property

class User(Base):
    __tablename__ = 'user'

    id = Column(Integer, primary_key=True)
    name = column_property(Column(String(50)), active_history=True)

column_property() 也用于将单个属性映射到多个列。当映射到 join() 具有彼此相等的属性:

class User(Base):
    __table__ = user.join(address)

    # assign "user.id", "address.user_id" to the
    # "id" attribute
    id = column_property(user_table.c.id, address_table.c.user_id)

有关此用法的更多示例,请参见 根据多个表映射类 .

另一个地方 column_property() 需要的是将SQL表达式指定为映射属性,如下面创建属性的位置 fullname 这是 firstnamelastname 柱::

class User(Base):
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True)
    firstname = Column(String(50))
    lastname = Column(String(50))
    fullname = column_property(firstname + " " + lastname)

有关此用法的示例,请参阅 作为映射属性的SQL表达式 .

Object Name Description

column_property(*columns, **kwargs)

提供列级属性以与映射一起使用。

function sqlalchemy.orm.column_property(*columns, **kwargs)

提供列级属性以与映射一起使用。

基于列的属性通常可以应用于映射器的 properties 字典使用 Column 元素直接。当给定列不直接出现在映射器的可选列中时,请使用此函数;示例包括SQL表达式、函数和标量选择查询。

这个 column_property() 函数返回 ColumnProperty .

映射器的可选项中不存在的列不会被映射器持久化,并且是有效的“只读”属性。

参数
  • *cols -- 要映射的列对象列表。

  • active_history=False -- 什么时候? True 指示如果尚未加载,则在替换时应加载标量属性的“上一个”值。通常,简单非主键标量值的历史跟踪逻辑只需要知道“new”值即可执行刷新。此标志可用于使用 get_history()Session.is_modified() 它还需要知道属性的“上一个”值。

  • comparator_factory -- 扩展的类 Comparator 它为比较操作提供自定义SQL子句生成。

  • group -- 当标记为延迟时,此属性的组名。

  • deferred -- 如果为true,则列属性为“deferred”,这意味着它不会立即加载,而是在实例上首次访问属性时加载。也见 deferred() .

  • doc -- 将作为类绑定描述符上的文档应用的可选字符串。

  • expire_on_flush=True -- 清除时禁用到期。引用SQL表达式(而不是单个表绑定列)的列_property()被视为“只读”属性;填充它不会影响数据状态,并且只能返回数据库状态。因此,每当父对象涉及刷新时,列_property()的值就会过期,也就是说,在刷新中具有任何类型的“脏”状态。将此参数设置为 False 将在冲洗后留下任何现有值。但是请注意 Session 默认的过期设置仍然会在 Session.commit() 但是,打电话来。

  • info -- 可选数据字典,将填充到 MapperProperty.info 此对象的属性。

  • raiseload -- 如果为True,则指示列在未出错时应引发错误,而不是加载值。可以在查询时使用 deferred() raiseload=False的选项。。版本添加::1.4。。另请参见: 延迟列的Raiseload

参见

对列级别选项使用列属性 -在包含映射选项的同时映射列

使用列属性 -映射SQL表达式

映射表列的子集

有时,A Table 使用反射过程使对象可用,如 反映数据库对象 从数据库加载表的结构。对于这样一个表,如果有许多列不需要在应用程序中引用,则 include_propertiesexclude_properties 参数可以指定只映射列的子集。例如::

class User(Base):
    __table__ = user_table
    __mapper_args__ = {
        'include_properties' :['user_id', 'user_name']
    }

…将映射 User 类到 user_table 表,仅包括 user_iduser_name 列-其余部分不被引用。类似::

class Address(Base):
    __table__ = address_table
    __mapper_args__ = {
        'exclude_properties' : ['street', 'city', 'state', 'zip']
    }

…将映射 Address 类到 address_table 表,包括除 streetcitystatezip .

使用此映射时,未包含的列将不会在由发出的任何select语句中引用 Query 也不会在表示列的已映射类上有任何已映射属性;指定该名称的属性除了正常的python属性分配之外没有任何效果。

在某些情况下,多个列可能具有相同的名称,例如当映射到共享某个列名称的两个或多个表的联接时。 include_propertiesexclude_properties 也可以容纳 Column 要更准确地描述应包括或排除哪些列的对象::

class UserAddress(Base):
    __table__ = user_table.join(addresses_table)
    __mapper_args__ = {
        'exclude_properties' :[address_table.c.id],
        'primary_key' : [user_table.c.id]
    }

注解

插入和更新个人配置的默认值 Column 对象,即 列插入/更新默认值 包括由 Column.defaultColumn.onupdateColumn.server_defaultColumn.server_onupdate 参数,即使这些参数 Column 对象未映射。这是因为在 Column.defaultColumn.onupdate , the Column 对象仍存在于基础上 Table 从而允许默认函数在ORM发出插入或更新时发生,并且在 Column.server_defaultColumn.server_onupdate 关系数据库本身将这些默认值作为服务器端行为发出。

Previous: 映射列和表达式 Next: 作为映射属性的SQL表达式