【发布时间】:2012-12-07 10:30:04
【问题描述】:
我正在尝试在使用 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,
...
}
【问题讨论】:
-
在
session.commit()之后还要session.explunge_all() -
@van:这听起来应该有所帮助,但遗憾的是它并没有改变任何东西。内存使用量会暂时保持稳定,但会继续上升。
-
我想知道这是否是增加内存使用量的
XML部分(而不是SA部分)。 -
这听起来不像是 SQLAlchemy 方面的问题。你的模型对象是做什么的?你能提供一个工作的例子吗?如果您查看 gc.get_objects() 的更改会发生什么,实际上添加了哪些类型的对象?
-
@van:我专门重写了 XML 部分以使用很少的 RAM。该脚本需要大约 20 分钟才能运行,并且在遍历 XML 数据时,我的 RAM 使用量保持不变(波动 20mb)。一旦 SQLAlchemy 部分启动,内存使用量就会开始增长。
标签: python memory sqlalchemy