我想弄清楚如何映射一个简单的只读属性,并保存到数据库时,该属性触发。SQLAlchemy - 如何映射一个只读(或计算)的属性
一个人为的例子应该使这个更清楚。首先,一个简单的表:
meta = MetaData()
foo_table = Table('foo', meta,
Column('id', String(3), primary_key=True),
Column('description', String(64), nullable=False),
Column('calculated_value', Integer, nullable=False),
)
我想要做的是建立一个只读属性的类时,我打电话session.commit(将插入calculated_value柱对我来说)...
import datetime
def Foo(object):
def __init__(self, id, description):
self.id = id
self.description = description
@property
def calculated_value(self):
self._calculated_value = datetime.datetime.now().second + 10
return self._calculated_value
按照SQLAlchemy的文档,我觉得我应该映射此像这样:
mapper(Foo, foo_table, properties = {
'calculated_value' : synonym('_calculated_value', map_column=True)
})
的问题,这是_calculated_在您访问calculated_value属性之前,值为None。看来SQLAlchemy在插入到数据库时没有调用该属性,所以我得到一个None值。映射它的正确方法是什么,以便“calculate_value”属性的结果插入到foo表的“calculated_value”列中?
好的 - 我在编辑这篇文章,以防其他人有相同的问题。我最终做的是使用MapperExtension。让我给你一个更好的例子以及扩展的用法:
class UpdatePropertiesExtension(MapperExtension):
def __init__(self, properties):
self.properties = properties
def _update_properties(self, instance):
# We simply need to access our read only property one time before it gets
# inserted into the database.
for property in self.properties:
getattr(instance, property)
def before_insert(self, mapper, connection, instance):
self._update_properties(instance)
def before_update(self, mapper, connection, instance):
self._update_properties(instance)
这就是你如何使用这个。比方说,你有一个只有几个只读属性的类,它必须在插入到数据库之前触发。我在这里假设,对于这些只读属性中的每一个,都需要在数据库中有一个相应的列,用于填充属性的值。你还是要建立一个代名词每个属性,但您使用映射扩展名,当你映射对象上面:
class Foo(object):
def __init__(self, id, description):
self.id = id
self.description = description
self.items = []
self.some_other_items = []
@property
def item_sum(self):
self._item_sum = 0
for item in self.items:
self._item_sum += item.some_value
return self._item_sum
@property
def some_other_property(self):
self._some_other_property = 0
.... code to generate _some_other_property on the fly....
return self._some_other_property
mapper(Foo, metadata,
extension = UpdatePropertiesExtension(['item_sum', 'some_other_property']),
properties = {
'item_sum' : synonym('_item_sum', map_column=True),
'some_other_property' : synonym('_some_other_property', map_column = True)
})
有趣。尽管我用稍微不同的方式解决了这个问题,但我将其标记为答案,因为它应该起作用。我越了解SQLAlchemy,我越喜欢它! – 2010-06-11 18:58:39