Предположим, я следующая схема в Pony ORM:Вычислены/полученные поля полностью поддерживаются в Pony ORM?
from pony.orm import *
db = Database("postgres", database='foo')
class Job(db.Entity):
job_id = PrimaryKey(int, auto=True)
job_name = Required(str)
base_salary = Required(int)
multiplier = Required(int, default=1000)
people = Set(lambda: Person)
class Person(db.Entity):
person_id = PrimaryKey(int, auto=True)
name = Required(str)
job = Required(lambda: Job)
experience = Required(int)
Я хотел бы Person
объект, чтобы иметь атрибут salary
, что это равно:
Job.base_salary + (Person.experience * Job.multiplier)
Моя первая мысль была, чтобы добавить свойство к Лицо, подобное этому:
@property
def salary(self):
return self.job.base_salary + (self.experience * self.job.multiplier)
Это работает для простого запроса:
j1 = Job(job_name = "Astronaut", base_salary = 80000, multiplier = 5000)
j2 = Job(job_name = "Butcher", base_salary = 40000, multiplier = 2000)
j3 = Job(job_name = "Chef", base_salary = 30000)
for i, name in enumerate(["Alice", "Bob", "Carol"]):
p = Person(name = name, job=j1, experience = i)
for i, name in enumerate(["Dave", "Erin"]):
p = Person(name = name, job=j2, experience = i)
for i, name in enumerate(["Frank", "Gwen"]):
p = Person(name = name, job=j3, experience = i)
for p in select(p for p in Person):
print p.name, p.experience, p.salary
Печать:
Alice 2 90000
Bob 4 100000
Carol 6 110000
Dave 2 44000
Erin 4 48000
Frank 2 32000
Gwen 4 34000
Но если я пытаюсь что-то вроде этого:
for j in select((j.job_name, avg(j.people.salary)) for j in Job):
print j
Возможно, не удивительно, я получаю:
AttributeError: j.people.salary
так salary
не является «реальный» атрибут. Есть ли способ сделать такие вещи, которые позволили бы вычисляемым полям рассматриваться как первоклассные объекты, которые могут иметь нормальную агрегацию/расчеты, выполненные на них?
Прохладный, с нетерпением жду этого! – tonycpsu