如何以正确的方式复制SQLAlchemy映射对象?

时间:2015-03-13 18:40:19

标签: python sqlalchemy

我想复制(复制)SQLAlchemy映射的对象。它应该只复制我创建的数据,而不是所有的内容。它不应该复制主键或唯一值。

这在创建与上一个数据条目略有不同的新数据条目时非常有用。因此,用户无需再次输入所有数据。

重要要求是这需要在表格中的列名称(例如name)和python类中的成员名称(例如_name)时起作用不一样。

此(简化)代码适用于所有declarative_base()派生类但仅当col-name和member-name相同时才会生效。

import sqlalchemy as sa

def DuplicateObject(oldObj):
    mapper = sa.inspect(type(oldObj))
    newObj = type(oldObj)()

    for col in mapper.columns:
        # no PrimaryKey not Unique
        if not col.primary_key and not col.unique:
            setattr(newObj, col.key, getattr(oldObj, col.key))

    return newObj

col.key是表格中列的名称。当python类中的成员名称不同时,这将不起作用。我不知道SQLAlchemy如何将column-name与member-name连接起来。 SQLA如何知道这种连接?我该如何照顾它?

1 个答案:

答案 0 :(得分:0)

import sqlalchemy as sqa

def DuplicateObject(oldObj):
    # SQLAlchemy related data class?
    if not isinstance(oldObj, _Base):
        raise TypeError('The given parameter with type {} is not ' \
            'mapped by SQLAlchemy.'.format(type(oldObj)))

    mapper = sa.inspect(type(oldObj))
    newObj = type(oldObj)()

    for name, col in mapper.columns.items():
        # no PrimaryKey not Unique
        if not col.primary_key and not col.unique:
            setattr(newObj, name, getattr(oldObj, name))

    return newObj

看起来这个工作。即使成员以双下划线开始(__name)。

但有人SQLA-mailinglist mentioned

  但是,这不是全世界的通用解决方案。它不考虑作为独立的UniqueConstraint对象中提到的唯一Index对象或列的一部分的列。

但是因为SQLA-docu(对我而言)很难阅读和理解,我不确定该代码中发生了什么 - 特别是在for - 构造中。 items()背后的内容以及为什么有两个参数(namecol)?