gpt4 book ai didi

python - SQLAlchemy 吃 RAM

转载 作者:太空狗 更新时间:2023-10-29 22:23:08 25 4
gpt4 key购买 nike

我试图在用 Python 处理后将一些 XML 数据导入我的 MySQL 数据库。为了简单起见,我通过一个使用 SQLAlchemy 访问我的数据库的脚本来完成这一切。

XML 文件有大约 80,000 个条目,我使用 xml.etree.cElementTreeiterparse 方法处理它,并在使用它们后删除节点以保持内存使用大约 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, 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 扩展中的“十进制”结果处理器发生泄漏。

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

0.5.5 - 修复了当对象被 unpickle 并放回 session 时潜在的内存泄漏

0.5.4 - 对 session 的内存使用进行了重大改进。您肯定希望顺利通过此版本。

关于python - SQLAlchemy 吃 RAM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13761276/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com