Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove deferred attribute of SQLAlchemy entity from memory?

For example we have a table that stores LONGBLOB objects:

class MyEntity(_base):
    id = Column('ID', Integer, primary_key=True)
    metadata = Column('META', String(512), nullable=False)
    bigData = deferred(Column('BIG_DATA', LONGBLOB, nullable=False))

Column with LONGBLOB marked as deferred, i.e. it is loaded only on access to this attribute of particular object.

I need to query list of objects from the database and iterate over collection:

entities = dbSession.query(MyEntity).all()
for entity in entities:
    ...
    entity.bigData  # load BLOB from the database and do smth with data
    ...

In this loop all BLOBs will be loaded from database and memory will be exhausted. I need a way to clean memory at the end of each cycle. Expunge object from session and remove from memory entirely is not handy...

How to clean up particular attribute of the object (LONGBLOB) but do not remove object from the session?

like image 229
Victor Mezrin Avatar asked Oct 18 '16 21:10

Victor Mezrin


People also ask

What does all () do in SQLAlchemy?

all() method. The Query object, when asked to return full entities, will deduplicate entries based on primary key, meaning if the same primary key value would appear in the results more than once, only one object of that primary key would be present.

What is _sa_instance_state in SQLAlchemy?

_sa_instance_state is a non-database-persisted value used by SQLAlchemy internally (it refers to the InstanceState for the instance.

What does Session rollback () do?

Session. commit() means that the changes made to the objects in the Session so far will be persisted into the database while Session. rollback() means those changes will be discarded. Session.

What is Session flush in SQLAlchemy?

session. flush() communicates a series of operations to the database (insert, update, delete). The database maintains them as pending operations in a transaction.


1 Answers

Don't load bigData into the object. The deferred loading is already doing a query per iteration, so you can do that yourself without associating it with the MyEntity instance:

entities = dbSession.query(MyEntity).all()
for entity in entities:
    bigData = session.query(MyEntity.bigData).filter_by(id=entity.id).scalar()

bigData should be cleaned up as long as no references to it are kept around.

like image 181
RazerM Avatar answered Sep 25 '22 06:09

RazerM