Python 使用SQLite了解PonyORM中的内存消耗
我有以下代码将一个大型CSV文件(超过350万行)加载到SQLite数据库中 该程序工作正常,但似乎没有释放内存,因此在运行该程序时,我可以通过命令Python 使用SQLite了解PonyORM中的内存消耗,python,sqlite,memory-leaks,orm,ponyorm,Python,Sqlite,Memory Leaks,Orm,Ponyorm,我有以下代码将一个大型CSV文件(超过350万行)加载到SQLite数据库中 该程序工作正常,但似乎没有释放内存,因此在运行该程序时,我可以通过命令top看到其内存大小如何增长,直到耗尽所有可用的服务器内存,并且在不插入所有行的情况下终止该程序 我的理解是,包含的db.commit()(每次我们开始在CSV中加载一个新的月份时都会执行)将释放创建的任何烛台实例(我认为,这些实例是导致内存增长的实例),但它不会这样做 为什么会发生这种情况,代码中有什么可以纠正的,以使其在没有内存泄漏的情况下工作
top
看到其内存大小如何增长,直到耗尽所有可用的服务器内存,并且在不插入所有行的情况下终止该程序
我的理解是,包含的db.commit()
(每次我们开始在CSV中加载一个新的月份时都会执行)将释放创建的任何烛台实例(我认为,这些实例是导致内存增长的实例),但它不会这样做
为什么会发生这种情况,代码中有什么可以纠正的,以使其在没有内存泄漏的情况下工作
#-*-编码:utf-8-*-
#将CSV数据加载到SQLite数据库中
从十进制输入*
从日期时间导入日期时间
从pytz导入时区
从小马进口*
导入csv
#输入参数
csv_文件名='dax-1m.csv'
csv_时间范围='1m'
csv_分隔符=';'
csv“u quotechar=”
csv\u时区=时区(“美国/纽约”)
db_filename='dax.db'
db_时区=时区(“欧洲/柏林”)
#打开/创建数据库
db=数据库()
#数据模型
类烛台(db.Entity):
时间框架=必需(unicode)
时间戳=必需(日期时间)
打开=必需(十进制,精度=12,刻度=6)
高=必需(十进制,精度=12,刻度=6)
低=必需(十进制,精度=12,刻度=6)
关闭=必需(十进制,精度=12,刻度=6)
体积=所需(十进制,精度=12,刻度=6)
bind(provider='sqlite',filename=db\u filename,create\u db=True)
db.generate_映射(create_tables=True)
#装载机等级
类加载器():
def加载(自):
行数=0;
本年度=-1;
本月=-1;
打开(csv_文件名,换行符=“”)作为csvfile:
r=csv.reader(csvfile,delimiter=csv_delimiter,quotechar=csv_quotechar)
使用db_会话:
对于r中的行:
_年份=整数(第[0][4]行)
_月份=整数(第[0][3:-5]行)
_day=int(第[0][:2]行)
_小时=整数(第[1][:2]行)
_分钟=整数(第[1][3:5]行)
csv\u dt=日期时间(年、月、日、小时、分钟)
db_dt=csv_时区。本地化(csv_dt)。像散区(db_时区)
烛台(
timeframe=db_timezone.zone,
时间戳=db_dt,
打开=第[2]行,
高=第[3]行,
低=第[4]行,
关闭=第[5]行,
体积=第[6]行
)
行计数+=1
如果(\u年!=当前年或\u月!=当前月):
db.commit()
本年度=\u年度
当前月份=\u月份
打印('+str(当前年)+'+str(当前月)+'..的加载数据)
打印('已加载'+str(行计数)+'寄存器')
ldr=Loader()
ldr.load();
此处没有内存泄漏。小马在离开db_会话作用域时清除缓存
在这里你可以看到更多关于这个的信息
特别是这个:
会话结束时,将执行以下操作:
- 清除标识映射缓存
with db_session(strict=True):
for i, row in enumerate(r):
<do some work>
if i % 10000 == 0:
commit() # save the changes
rollback() # clear the cache
具有db_会话的(strict=True):
对于i,枚举(r)中的行:
如果i%10000==0:
提交()#保存更改
回滚()#清除缓存
有关回滚()的详细信息,请参见此处: