映射表列

优质
小牛编辑
129浏览
2023-12-01

的默认行为 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)

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

参见

DDLEvents.column_reflect()

截取列定义 -在 自动程序 文档

用前缀命名所有列

一种快速的列名称前缀方法,通常在映射到现有列名称时使用。 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 NameDescription

column_property(*columns, **kwargs)

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

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

有时,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 关系数据库本身将这些默认值作为服务器端行为发出。