python – SQLAlchemy吃RAM
我正在尝试使用
Python处理它后将一些XML数据导入我的MySQL数据库.为了简单起见,我在一个使用SQLAlchemy访问我的数据库的脚本中完成所有操作.
XML文件有大约80,000个条目,我使用xml.etree.cElementTree的iterparse方法处理它,并在使用它们之后删除节点以使我的内存使用量保持在20mb左右. 一旦我包含SQLAlchemy并开始向数据库添加内容,我的内存使用量每秒增加大约10mb,直到脚本耗尽了我的所有内存并且操作系统将其杀死. 这基本上是我的代码的样子: index = 0 for element in iterate_xml(): ... index += 1 session.add(Model(**data)) if index % 1000 == 0: session.flush() session.commit() 我不知道还有什么可以尝试的.定期的.flush()和.commit()确实有所帮助,但它们无法解决问题. SQLAlchemy不适合执行此任务吗? 我像这样设置SQLAlchemy: 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 } structure是一个将列名映射到数据类型的字典(它是从XML生成的): structure = { 'column_name': SQLAlchemyDataType,... } 解决方法
这是代码的SQLAlchemy版本.在0.7和0.8的测试中,它不泄漏任何内存,这对我来说并不意外,因为我们在持续集成下进行了十几次测试,以确保在许多情况下没有任何泄漏.因此,第一步是确认此脚本不会泄漏,然后尝试找出此脚本与您之间的更改,以生成实际显示泄漏内存的测试用例.
from sqlalchemy import Column,String,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扩展中的“十进制”结果处理器有泄漏. 0.6.6 – 如果用于以某种方式选择行,则SQLSoup扩展被识别为具有潜在泄漏(SQLSoup现在是它自己的项目) 0.5.5 – 当对象被打开并放回会话时固定潜在的内存泄漏 0.5.4 – 对会话的内存使用进行了重大改进.你肯定想要超越这个版本. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |