Basit bir salt okunur özelliğe karşı eşleme yapmanın nasıl bir yol olduğunu bulmaya çalışıyorum ve veritabanına kaydederken bu özelliğin yangına neden olduğunu düşünüyorum.SQLAlchemy - salt okunur (veya hesaplanmış) özelliğe karşı eşleme nasıl yapılır
Bunun için bir örnek, bunu daha açık hale getirmelidir. İlk olarak, basit tablo:
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),
)
Ya ben session.commit (çağırdığınızda benim için calculated_value sütuna ekler salt okunur bir özelliğe sahip bir sınıf kurulur yapmak istiyorum) ...
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 docs göre ben şöyle bu harita gerekiyor düşünüyorum :
mapper(Foo, foo_table, properties = {
'calculated_value' : synonym('_calculated_value', map_column=True)
})
bu sorun o _calculated_ olduğunu value_value özelliğine erişene kadar değer Yoktur. SQLAlchemy, veritabanına ekleme üzerine özelliği çağırmıyor gibi görünüyor, bu yüzden bunun yerine bir None değeri alıyorum. Bunu "map_value" özelliğinin sonucu foo tablosunun "calculation_değer_değer" sütununa eklenecek şekilde eşlemek için doğru yol nedir?
Tamam - Başka birinin aynı soruna sahip olması durumunda bu gönderiyi düzenliyorum. Yaptığım şey bir MapperExtension kullanmaktı. Uzantının kullanımıyla birlikte size daha iyi bir örnek vereyim:
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)
Bu şekilde kullanabilirsiniz. Veritabanına yerleştirilmeden önce yanması gereken birkaç salt okunur özelliği olan bir sınıfa sahip olduğunuzu söyleyelim. Bu salt okunur özelliklerin her biri için, veritabanında, mülkün değeri ile doldurulmasını istediğiniz karşılık gelen bir sütun var. Hala her özellik için eşanlamlısını kurmak için gidiyoruz, ancak nesneyi map yukarıdaki mapper uzantısını kullanan:
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)
})
İlginç.Bunu biraz farklı bir şekilde çözsem de, bunu cevap olarak işaretledim çünkü işe yarayacaktı. SQLAlchemy hakkında ne kadar çok şey öğrenirse, o kadar çok severim! –