mapper()的默认行为是将映射的Table中的所有列汇编为映射对象属性,每个列都根据列本身的名称进行命名特别是Column的key属性)。这种行为可以通过几种方式进行修改。
默认情况下,映射与Column共享与映射属性相同的名称 - 具体而言,它匹配Column上的Column.key属性,默认情况下它与Column.name相同。
分配给映射到Column的Python属性的名称可以与Column.name或Column.key不同,只需通过指定正如我们在声明性映射中所说明的那样:
class User(Base):
    __tablename__ = 'user'
    id = Column('user_id', Integer, primary_key=True)
    name = Column('user_name', String(50))Where above User.id resolves to a column named user_id and User.name resolves to a column named user_name.
映射到现有表格时,可以直接引用Column对象:
class User(Base):
    __table__ = user_table
    id = user_table.c.user_id
    name = user_table.c.user_name或者在经典的映射中,使用所需的键将其放置在properties字典中:
mapper(User, user_table, properties={
   'id': user_table.c.user_id,
   'name': user_table.c.user_name,
})在下一节中,我们将更仔细地检查.key的用法。
在上一节Naming Columns Distinctly from Attribute Names中,我们展示了显式映射到类的Column如何可以具有与该列不同的属性名称。但是,如果我们没有明确列出Column对象,而是使用反射自动生成Table对象(例如,如Reflecting Database Objects在这种情况下,我们可以利用DDLEvents.column_reflect()事件来拦截Column对象的生成并为它们提供Column.key
@event.listens_for(Table, "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=True, autoload_with=some_engine)如果我们想限定事件只对上面的特定MetaData对象作出反应,我们可以在我们的事件中检查它:
@event.listens_for(Table, "column_reflect")
def column_reflect(inspector, table, column_info):
    if table.metadata is Base.metadata:
        # set column.key = "attr_<lower_case_name>"
        column_info['key'] = "attr_%s" % column_info['name'].lower()通常在映射到现有的Table对象时使用column_prefix作为列名前缀的快速方法:
class User(Base):
    __table__ = user_table
    __mapper_args__ = {'column_prefix':'_'}以上将放置诸如_user_id,_user_name,_password等属性名称。在映射的User类上。
这种方法在现代用法中不常见。为了处理反映表,更灵活的方法是使用Automating Column Naming Schemes from Reflected Tables中描述的方法。
使用column_property()函数映射Column时可以指定选项。该函数明确地创建mapper()用于跟踪Column的ColumnProperty;通常,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() is also used to map a single attribute to multiple columns. 这个用例映射到一个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)有关此用法的更多示例,请参阅Mapping a Class against Multiple Tables。
需要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 Expressions as Mapped Attributes中查看此用法的示例。
sqlalchemy.orm.column_property(*columns, **kwargs)¶提供用于Mapper的列级属性。
通常可以直接使用Column元素将基于列的属性应用于映射器的properties字典。当给定的列不直接存在于映射器的可选择范围内时使用此函数;示例包括SQL表达式,函数和标量SELECT查询。
不存在于映射器可选择的列将不会被映射器持久化并且是有效的“只读”属性。
| 参数: | 
 | 
|---|
有时,使用Reflecting Database Objects中描述的反映过程来使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。
使用此映射时,未包含的列将不会在由Query发出的任何SELECT语句中引用,也不会在表示该列的映射类上存在任何映射属性;分配该名称的属性将不会超出正常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]
    }注意
insert and update defaults configured on individual Column objects, i.e. those described at Column Insert/Update Defaults including those configured by the default, update, server_default and server_onupdate arguments, will continue to function normally even if those Column objects are not mapped. 这是因为在default和update的情况下,Column对象仍然存在于Table中,从而允许默认函数在ORM发出INSERT或UPDATE时发生,而在server_default和server_onupdate的情况下,关系数据库本身维护这些函数。