SQLAlchemy吃RAM

时间:2012-12-07 10:30:05

标签: python memory sqlalchemy

我正在尝试使用Python处理它后将一些XML数据导入我的MySQL数据库。为了简单起见,我在一个使用SQLAlchemy访问我的数据库的脚本中完成所有操作。

XML文件有大约80,000个条目,我使用xml.etree.cElementTree的{​​{1}}方法处理它,并在使用它们之后删除节点,以使我的内存使用量保持在20mb左右。

一旦我加入SQLAlchemy并开始向数据库添加内容,我的内存使用量每秒增加大约10mb,直到脚本耗尽了我的所有内存并且操作系统将其杀死。

这基本上就是我的代码:

iterparse

我不确定还有什么可以尝试的。定期index = 0 for element in iterate_xml(): ... index += 1 session.add(Model(**data)) if index % 1000 == 0: session.flush() session.commit() .flush()会有所帮助,但他们无法解决问题。

SQLAlchemy不适合执行此任务吗?


我像这样设置SQLAlchemy:

.commit()

我的桌子看起来像这样:

Base = declarative_base()
engine = create_engine(config.SQLALCHEMY_DATABASE_URI, echo=False)

Session = sessionmaker(bind=engine, autoflush=False, expire_on_commit=False)
session = Session()

columns = [] for name, datatype in structure.iteritems(): if isinstance(datatype, int): datatype = String(datatype or 20) column = Column(name, datatype) columns.append(column) metadata = MetaData(bind=engine) table = Table('table_name', metadata, Column('id', Integer, primary_key=True), *columns ) metadata.drop_all(engine) metadata.create_all(engine) class MyTable(Base): __tablename__ = 'table_name' __table_args__ = { 'autoload': True, 'autoload_with': engine } 是一个将列名映射到数据类型的字典(它是从XML生成的):

structure

1 个答案:

答案 0 :(得分:9)

这是一个仅限SQLAlchemy版本的代码。在0.7和0.8的测试中,它不泄漏任何内存,这对我来说并不意外,因为我们在持续集成下进行了十几次测试,以确保在许多情况下没有任何泄漏。因此,第一步是确认此脚本不会泄露给您,然后尝试找出此脚本与您之间的更改,以生成实际显示泄漏内存的测试用例。

from sqlalchemy import Column, String, Integer, create_engine
from sqlalchemy.orm import Session
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Model(Base):
    __tablename__ = "a"

    id = Column(Integer, primary_key=True)
    data = Column(String)

e = create_engine("sqlite:///somefile.db")

Base.metadata.create_all(e)

session = Session(e)

for index in xrange(10000000):
    session.add(Model(data="data %d" % index))

    if index % 1000 == 0:
        print "flushing... %d" % index
        session.flush()
        session.commit()

重要的是要注意SQLAlchemy过去泄露内存的那些问题。这是最近修复泄漏的历史:

0.7.8 - 最近的。此处修复的泄漏仅在以下情况下发生:1。C扩展,2。pyodbc驱动程序,在某些结果获取操作期间(不是全部)

0.6.6 - C扩展中的“Decimal”结果处理器有泄漏。

0.6.6 - 如果用于以某种方式选择行,SQLSoup扩展被识别为具有潜在泄漏(SQLSoup现在是它自己的项目)

0.5.5 - 当对象被打开并放回会话时固定潜在的内存泄漏

0.5.4 - 对Session的内存使用进行了重大改进。你肯定希望远远超过这个版本。