我想弄清楚如何映射一個簡單的只讀屬性,並保存到數據庫時,該屬性觸發。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