SQLAlchemy - 使用数据库列名称而不是属性名称在模型中设置值

时间:2011-06-29 15:33:14

标签: python database model sqlalchemy mapping

我有一个包含TS_TEST_ID列的表格。我有一个SQLAlchemy模型,具有以下属性:

id = Column(u'TS_TEST_ID', INTEGER(), primary_key=True, nullable=False)

当只知道id时,有没有办法在我的模型类的实例上设置TS_TEST_ID?也就是说,我只知道数据库中列的名称,我想以某种方式将其映射到id并在我的模型上设置id属性。我希望只是MyModel(**{'TS_TEST_ID':1})可以工作,但我收到以下错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 4, in __init__
  File "C:\Python26\lib\site-packages\sqlalchemy\orm\state.py", line 111,
   in initialize_instance
    return manager.events.original_init(*mixed[1:], **kwargs)
  File "C:\Python26\lib\site-packages\sqlalchemy\ext\declarative.py", line 1377,
   in _declarative_constructor
    (k, cls_.__name__))
TypeError: 'TS_TEST_ID' is an invalid keyword argument for MyModel

我不想为模型中的每一列定义TS_TEST_ID = Column(u'TS_TEST_ID', INTEGER(), primary_key=True, nullable=False),或者甚至是一个名为TS_TEST_ID的方法,它返回id属性。

2 个答案:

答案 0 :(得分:2)

这似乎比它需要的更复杂,但它确实有效。我希望有更直接的方法来做到这一点......

@staticmethod
def fromFieldHash(h):
    row = MyModel()
    cols = list(row.__table__._columns)
    for k, v in h.iteritems():
        col = find(lambda c: c.key == k, cols)
        # See http://www.sqlalchemy.org/trac/wiki/06Migration#AnImportantExpressionLanguageGotcha
        if col is not None:
            prop = row.__mapper__._columntoproperty[col].key
            setattr(row, prop, v)
    return row

我使用的find方法来自Cleanest Python find-in-list function

答案 1 :(得分:0)

如果希望scala> Trait.f(C1("hello", "world")) res0: String = hello scala> Trait.f(C2("hello", "world")) res1: String = hello scala> Trait.f(C3("hello", "world")) res2: String = world 同时处理属性和列,尽管拥有专用的__init__工厂似乎是一种更干净的方法,但可以将以下实现用作抽象基础:

classmethod

使用以上内容,可以通过以下断言:

from sqlalchemy import inspect
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()


def _create_col_lookup(mapper):
    return {c.name: k for k, c in mapper.columns.items()}


class ColBase(Base):

    __abstract__ = True

    def __init__(self, *args, **kwargs):
        # Create a lookup of column name -> attr key
        ctoa = _create_col_lookup(inspect(self).mapper)

        # Process intersecting keys
        for k in ctoa.keys() & kwargs.keys():
            setattr(self, ctoa[k], kwargs.pop(k))

        super().__init__(*args, **kwargs)