0

私は sqlalchemy を学んでおり、自分のプロジェクトで使用したいと考えています。私のプロジェクトにはツリー構造と多くのノードが含まれているため、オブジェクトが DB に永続化された後にメモリを解放したいと考えています。

しかし、これについて sqlalchemy のいくつかのテストを行ったとき、作成されたオブジェクトがガベージ コレクションされないことに混乱しました。

ここに私のテストコードがあります:

from sqlalchemy import (create_engine, Column, select, case,
func, ForeignKey)
from sqlalchemy import Integer, String, Boolean
from sqlalchemy.orm import sessionmaker, MapperExtension, aliased
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.declarative import declarative_base
import weakref
import sys
import gc

engine = create_engine('sqlite://', echo=True)
Base = declarative_base()

class Cursor(Base):
    __tablename__ = 'cursor'

    id = Column(Integer, primary_key = True)
    spelling = Column(String, nullable = True)
    displayname = Column(String, nullable = False)
    usr = Column(String, nullable = True)
    is_definition = Column(Boolean, nullable = False)

    type_id = Column(Integer, ForeignKey('type.id'))
    type = relationship('Type',
                        backref = backref('instances', order_by = id))


class Type(Base):
    __tablename__ = 'type'

    id = Column(Integer, primary_key = True)

    is_const_qualified = Column(Boolean, nullable = False)


obj_type = Type(is_const_qualified=False)
type_ref = weakref.ref(obj_type)

print sys.getrefcount(obj_type)

obj_type = None
print type_ref()

次の出力が得られます。

3
<__main__.Type object at 0x268a490>

したがって、obj_typeをNoneに設定した後も、ガベージコレクションは行われず、まだ生きています。なぜこれが起こるのでしょうか?これがのメカニズムdeclarative_baseですか?

Python 2.7.3 と sqlalchemy 0.7.9 を使用していることに注意してください。

4

1 に答える 1

1

これは SQLAlchemy 0.8 でうまく機能しますが、0.7.9 ではどこかに循環があります。gc.collect()gc をテストするときは、サイクルを収集するために常に呼び出す必要があります。

obj_type = None
gc.collect()
print type_ref()

0.8 では、collect()cPython が使用されている場合、この特定のテストには必要ありません。

于 2013-06-21T19:09:37.610 に答える