Настройка базы данных «один ко многим» в Google App Engine - PullRequest
1 голос
/ 21 февраля 2011
class Student(db.Model):
    teacher = db.ReferenceProperty(Teacher, collection_name='students')
    name = db.StringProperty(required=True)
    zip_code = db.IntegerProperty(required=True)
    square_footage = db.IntegerProperty(required=True)
    month_entries = db.IntegerProperty(required=True)  

class Bill(db.Model):
    student = db.ReferenceProperty(Student, collection_name='bills')
    bill_month = db.DateProperty(required=True)
    energy = db.IntegerProperty(required=True)

Из настройки моих моделей, показанной выше ... Я могу легко показать все сохраненные купюры, используя что-то вроде этого:

bill = models.Bill.all()
for stubs in bill:
    print stubs.energy
    print stubs.student.name

Но как мне перечислить, какие счета есть у каждого студента? В SQL я бы сказал что-то вроде:

SELECT * FROM Bill WHERE Student.Name = Samuel

Полагаю, я не понимаю, как получить счета, предоставленные ReferenceProperty. В GQL все не так просто. Как запросить по ссылочному свойству?

Ответы [ 3 ]

3 голосов
/ 21 февраля 2011

ReferenceProperty создает автоматический запрос в объекте, на который ссылаются (используя collection_name, если вы его предоставили, что вы и сделали):

sams_bills = Student.all().filter("name =", "Samuel").get().bills

sams_bills теперь представляет собой db.Query для счетов, которыйВы можете вызвать .fetch () для получения одного или нескольких счетов.

1 голос
/ 21 февраля 2011

Я думаю, что людям с опытом работы с SQL сложнее всего заполучить App Engine, так как многие вещи требуют двух запросов, чтобы получить желаемые результаты.Опыт работы с SQL в том, что почти никто не использует GQL.;)

0 голосов
/ 04 апреля 2011

Параметр collection_name элемента db.ReferenceProperty "student" в классе Bill уже настроил запрос для вас. Так что все, что вам нужно сделать, это:

student = Student.all().filter('name =', 'Samuel').get()
for bill in student.bills:
    logging.info('Student %s Month:%s Energy:%d' % (student.name, str(bill.bill_month), bill.energy)

Теперь результаты, возвращаемые запросом с обратной ссылкой, неупорядочены. Вы можете (если ваши индексы настроены правильно) использовать .order (), чтобы вернуть их в определенном порядке, или вы можете поместить их в набор и отсортировать их в памяти (очень быстро) следующим образом:

sorted_bills = []
for bill in student.bills:
    sorted_bills.append(bill)

# Sort additions by month then by amount (secondary key sorts first in code)
sorted_bills = sorted(sorted_bills, key=lambda Bill: Bill.energy, reverse=True)
sorted_bills = sorted(sorted_bills, key=lambda Bill: Bill.bill_month, reverse=False)

В этом примере, если у студента было более одного счета с одним и тем же значением bill_month, самые большие счета будут отсортированы первыми (обратите внимание на обратный параметр = True).

...