Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从SQLAlchemy会话中删除对象_Python_Sqlalchemy - Fatal编程技术网

Python 从SQLAlchemy会话中删除对象

Python 从SQLAlchemy会话中删除对象,python,sqlalchemy,Python,Sqlalchemy,我希望将映射类的实例传递给一个非SQLAlchemy感知的方法(在另一个进程中),并且只需要属性的值。问题是,每当方法想要读取属性值时,就会出现一个无界执行错误。我确实理解,为什么会发生这种情况,但我想找到解决这个问题的办法 我只需要定义的属性(示例中的id、name和dirty)的值,而不需要目标方法中的SQLAlchemy开销 示例类: Base = declarative_base() class Record(Base): __tablename__ = 'records'

我希望将映射类的实例传递给一个非SQLAlchemy感知的方法(在另一个进程中),并且只需要属性的值。问题是,每当方法想要读取属性值时,就会出现一个
无界执行错误。我确实理解,为什么会发生这种情况,但我想找到解决这个问题的办法

我只需要定义的属性(示例中的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)
呼叫示例:

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()
,但没有成功。

我猜您正在与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将您的对象变成一个“哑”对象,它与数据库没有连接,看起来非常像我刚才在这里创建的对象。但是我不知道它是什么。

您需要从会话中删除SQL ALchemy对象,也就是“删除”它。然后,您可以请求任何已加载的属性,而不是试图重用其上一个已知会话/未绑定会话的属性

self.expunge(record)
但是请注意,任何已卸载的属性都将返回其最后一个已知值,或者不返回。如果您希望以后再次使用该对象,可以再次调用“添加”或“合并”

self.add(record)

使用一个不是从
声明性_base()
继承的单独实例似乎是一个很好的解决方法,但我需要有两个几乎相同的类,我认为这是不必要的。也许我会找到一种使用多重继承的方法(一种是从
RecordData
中继承,另一种是从
declarative_base()
中继承)。@Manuel Faux:Python中的对象和类是高度可变的。也许可以编写一些从类记录自动生成类记录数据的东西,特别是如果您使用了SQLAlchemy添加到类记录中的额外数据。您甚至可以将该类存储为类记录的实例变量,这样就不必不断地重新生成它。