从SQLAlchemy会话中清除对象

Man*_*aux 7 python sqlalchemy

我想将映射类的实例传递给非SQLAlchemy感知方法(在另一个进程中),并且只需要我的属性的值.问题是,UnboundExecutionError每次方法想要读取属性值时都会发生.我明白,为什么会发生这种情况,但我想为这个问题找到解决方案.

我只需要我定义的属性的值(示例中的id,namedirty),并且不需要目标方法中的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
Run Code Online (Sandbox Code Playgroud)

示例电话:

...
def do_it(self):
    records = self.query.filter(Record.dirty == True)
    for record in records:
        pass_to_other_process(record)
Run Code Online (Sandbox Code Playgroud)

我已经尝试使用session.expunge()copy.copy(),但没有成功.

And*_*nez 13

您需要从会话中删除SQL ALchemy对象,即"删除"它.然后,您可以请求任何已加载的属性,而不是尝试重用其上次已知的会话/未绑定会话.

self.expunge(record)
Run Code Online (Sandbox Code Playgroud)

但请注意,任何未加载的属性都将返回其最后已知值或无.如果您想稍后再次使用该对象,您可以再次调用'add'或'merge'

self.add(record)
Run Code Online (Sandbox Code Playgroud)

  • 这里的 self 是指会话吗? (2认同)

Omn*_*ous 5

我的猜测是你正在与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
Run Code Online (Sandbox Code Playgroud)

然后......

def do_it(self):
    records = self.query.filter(Record.dirty == True)
    for record in records:
        pass_to_other_process(RecordData(record))
Run Code Online (Sandbox Code Playgroud)

现在,我认为有一种方法可以告诉SQLAlchemy将您的对象变成一个与数据库无关的"哑"对象,看起来非常像我刚才所做的.但我不知道它是什么.