Как работают выражения запросов web2py? - PullRequest
5 голосов
/ 03 марта 2012

Недавно у меня была возможность взглянуть на каркас web2py, и хотя у меня есть некоторый предыдущий опыт работы с Django и, тем более, с простым Python, я не смог разобраться в системе запросов, которую использует web2py.

Давайте возьмем этот пример из книги web2py

db = DAL('sqlite://storage.db')
myquery = (db.mytable.myfield > 'A')
myset = db(myquery)
rows = myset.select()
for row in rows:
    print row.myfield

В комментариях SO автор web2py говорит, что (db.mytable.myfield > 'A') напрямую не оценивается как True / Falseи это на самом деле оценивается для каждой строки во время выбора.Я понимаю, что именно это позволяет использовать эти выражения в качестве объектов запроса и даже объединять их.

Я пытался найти ответ на этот вопрос в Интернете, но не смог, поэтому вот мой вопрос: как этовыражения запроса не оцениваются как True / False сразу?Почему ценность myquery не, скажем, правда?Какая особенность Python, которую я, вероятно, упускаю, позволяет этому работать?

Ответы [ 3 ]

7 голосов
/ 03 марта 2012

В других ответах он есть, но только для того, чтобы предоставить немного больше деталей, специфичных для web2py:

db.mytable.myfield > 'A'

db.mytable.myfield является экземпляром класса web2py DAL Field, который наследуется от класса DAL Expression. Сам класс Expression перегружает ряд операторов Python, таких как ==, <, > и т. Д. Эти перегруженные операторы при применении к объектам Expression (и, следовательно, Field) возвращают экземпляр класса DAL Query, а не стандартного логического объекта Python. Вот исходный код для оператора > (__gt__).

См. здесь , чтобы узнать больше о перегрузке оператора в Python.

2 голосов
/ 03 марта 2012

db.mytable.myfield - это gluon.sql.SQLField, который переопределяет метод __gt__, так что выражение, использующее оператор>, приводит к gluon.sql.SQLQuery при оценке (см. http://www.web2py.com/examples/static/epydoc/web2py.gluon.dal.Expression-class.html).

2 голосов
/ 03 марта 2012

Любой оператор, применяемый к пользовательским (не встроенным) объектам на основе оценки специальных методов . Он широко известен как оператор перегрузки . Так что в основном определение класса поля выглядело одинаково:

class DBField(...):
#...

   def __gt__(self,value):
      #building query object, based on value
      return query
...