映射表列
的默认行为 mapper()
在映射的 Table
到映射的对象属性中,每个属性都根据列本身的名称命名(特别是 key
属性 Column
)这种行为可以通过几种方式进行修改。
从属性名称清楚地命名列
默认情况下,映射与 Column
与映射属性的相同-具体来说,它与 Column.key
属性对 Column
,默认与 Column.name
.
指定给映射到的python属性的名称 Column
可以不同于 Column.name
或 Column.key
正如我们在声明性映射中所演示的那样,只需按这种方式分配:
class User(Base): __tablename__ = 'user' id = Column('user_id', Integer, primary_key=True) name = Column('user_name', String(50))
在哪里 User.id
解析为名为的列 user_id
和 User.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
这是 firstname
和 lastname
柱::
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)
有时,A
Table
使用反射过程使对象可用,如 反映数据库对象 从数据库加载表的结构。对于这样一个表,如果有许多列不需要在应用程序中引用,则include_properties
或exclude_properties
参数可以指定只映射列的子集。例如::class User(Base): __table__ = user_table __mapper_args__ = { 'include_properties' :['user_id', 'user_name'] }
…将映射
User
类到user_table
表,仅包括user_id
和user_name
列-其余部分不被引用。类似::class Address(Base): __table__ = address_table __mapper_args__ = { 'exclude_properties' : ['street', 'city', 'state', 'zip'] }
…将映射
Address
类到address_table
表,包括除street
,city
,state
和zip
.使用此映射时,未包含的列将不会在由发出的任何select语句中引用
Query
也不会在表示列的已映射类上有任何已映射属性;指定该名称的属性除了正常的python属性分配之外没有任何效果。在某些情况下,多个列可能具有相同的名称,例如当映射到共享某个列名称的两个或多个表的联接时。
include_properties
和exclude_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.default
,Column.onupdate
,Column.server_default
和Column.server_onupdate
参数,即使这些参数Column
对象未映射。这是因为在Column.default
和Column.onupdate
, theColumn
对象仍存在于基础上Table
从而允许默认函数在ORM发出插入或更新时发生,并且在Column.server_default
和Column.server_onupdate
关系数据库本身将这些默认值作为服务器端行为发出。