Удалить объект из сеанса SQLAlchemy - PullRequest
7 голосов
/ 29 сентября 2010

Я хочу передать экземпляр сопоставленного класса методу, не поддерживающему SQLAlchemy (в другом процессе), и мне нужны только значения моих атрибутов. Проблема в том, что UnboundExecutionError возникает каждый раз, когда метод хочет прочитать значение атрибута. Я понимаю, почему это происходит, но я хотел бы найти решение этой проблемы.

Мне нужны только значения моих определенных атрибутов ( id , name и dirty в примере) и не требуются накладные расходы SQLAlchemy в месте назначения метод.

Пример класса:

Base = declarative_base()
class Record(Base):
    __tablename__ = 'records'
    _id = Column('id', Integer, primary_key=True)
    _name = Column('name', String(50))
    _dirty = Column('dirty', Boolean, index=True)

    @synonym_for('_id')
    @property
    def id(self):
        return self._id

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        self._name = value
        self._dirty = True

    name = synonym('_name', descriptor=name)

    @synonym_for('_dirty')
    @property
    def dirty(self):
        return self._dirty

Пример вызова:

...
def do_it(self):
    records = self.query.filter(Record.dirty == True)
    for record in records:
        pass_to_other_process(record)

Я пытался использовать session.expunge() и copy.copy(), но безуспешно.

Ответы [ 2 ]

12 голосов
/ 10 октября 2011

Вам необходимо удалить объект SQL ALchemy из сеанса, или «удалить его». Затем вы можете запросить любой уже загруженный атрибут без попытки повторно использовать его последний известный сеанс / несвязанный сеанс.

self.expunge(record)

Имейте в виду, что любой выгруженный атрибут вернет свое последнее известное значение или ничего. Если вы захотите позже поработать с объектом снова, вы можете просто снова вызвать «add» или «merge»

self.add(record)
5 голосов
/ 30 сентября 2010

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

class RecordData(object):
    __slots__ = ('id', 'name', 'dirty')

    def __init__(self, rec):
        self.id = rec.id
        self.name = rec.name
        self.dirty = rec.dirty

Потом позже ...

def do_it(self):
    records = self.query.filter(Record.dirty == True)
    for record in records:
        pass_to_other_process(RecordData(record))

Теперь я думаю, что есть способ заставить SQLAlchemy превратить ваш объект в «тупой» объект, который не имеет связи с базой данных и очень похож на то, что я только что сделал здесь. Но я не знаю, что это такое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...