declarative_base的子类不能被垃圾收集?

时间:2013-06-17 05:56:41

标签: python sqlalchemy

我正在学习sqlalchemy并希望在我的项目中使用它。因为我的项目涉及树结构和很多节点,所以我希望在对象持久存储在数据库后释放内存。

但是当我为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。

1 个答案:

答案 0 :(得分:1)

这在SQLAlchemy 0.8中效果更好,但是在0.7.9中只有一个循环。测试gc时,您总是需要调用gc.collect()来收集周期:

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

在0.8中,如果使用cPython,则此特定测试不需要collect()