2015-09-04 4 views
1

У меня есть некоторые определения моделей, где я переопределил их методы __repr__. Так, например, давайте принимать во внимание следующие объекты:Как можно избежать DatabaseSessionIsOver извне вызовов

def A(db.Entity): 
    id = PrimaryKey(int, auto=True) 
    name = Required(unicode) 
    b = Optional("B") 

    def __repr__(self): 
     return self.name 

def B(db.Entity): 
    id = PrimaryKey(int, auto=True) 
    name = Required(unicode) 
    a = Required("A") 

    def __repr__(self): 
     return '{n} from a={aname}'.format(n=self.name, aname = self.a) 

Это поднимает DatabaseSessionIsOver исключение в то время как я использовал метод search(B, 'aaaa) из Flask-PonyWhoosh, даже если он используется db_session завернуты внутрь:

@orm.db_session 
def search(model, *arg, **kw): 
    return model._wh_.search(*arg, **kw) 

Исключение возникает только тогда, когда какой-либо объект переопределяет метод __repr__ таким образом, который я сделал в приведенном выше примере.

Однако I'am использованием, чтобы избежать этой проблемы следующие предложения:

with db_session: 
    print(search(A, 'karl')) 

Так, в ближайшее время, вопрос в том, есть ли способ, чтобы избежать использования with ..., возможно, изменяя метод __repr__ или возможно, изменить методы из пакета ?.

Спасибо,

PD: Я читал prefetch method, но это, кажется, не подходит. Я не уверен.

ответ

1

Исключение DatabaseSessionIsOver происходит потому, что в вашем методе repr вы пытаетесь получить доступ к атрибуту отношения, который не был загружен из базы данных (self.a, который пытается вернуть атрибут A объекта name).

Одним из способов избежать этого исключения является загрузка всех необходимых объектов, прежде чем вы покинете db_session. В этом случае эти объекты будут размещаться на Карте идентификаторов, и никакой запрос к базе данных не потребуется.

Другой способ заключается в том, чтобы обернуть весь ваш код с большей областью db_session, поэтому, когда вы получаете доступ к атрибуту, который не был загружен из базы данных, Pony может сделать это в пределах db_session.

Пони требует использования @db_session, поскольку она устанавливает границы для разговора базы данных и позволяет освободить ресурсы:

  1. Очистить кэш Идентичность Карта
  2. Возвращает соединение с базой данных в пул соединений

Если мы не очистим кеш, то все объекты, которые были загружены из базы данных, будут находиться в памяти, пока вы не очистите кеш вручную или не закончите свою программу.

Предположим, мы вводим режим, когда db_session никогда не заканчивается, и вам необходимо очистить кеш вручную. Как вы думаете, это решит вашу проблему, и вы бы ее использовали?