【问题标题】:Understanding memory consumption in PonyORM with SQLite使用 SQLite 了解 PonyORM 中的内存消耗
【发布时间】:2019-01-26 03:22:09
【问题描述】:

我有以下代码将大型 CSV 文件(超过 350 万行)加载到 SQLite 数据库中。

该程序运行良好,但似乎它没有释放内存,因此在运行程序时我可以使用命令top 看到它的内存大小如何增长,直到耗尽所有可用的服务器内存并且程序在没有插入所有行的情况下被终止.

我的理解是,包含的 db.commit()(每次我们开始在 CSV 中加载新月份时执行)将释放所有创建的烛台实例(我认为是那些使内存增长的实例),但是它不这样做。

为什么会发生这种情况以及可以在代码中进行哪些更正以使其在没有这种内存泄漏的情况下工作?

# -*- coding: utf-8 -*-

# Load CSV Data into SQLite Database

from decimal import *
from datetime import datetime
from pytz import timezone

from pony.orm import *
import csv

# Input parameters
csv_filename = 'dax-1m.csv'
csv_timeframe = '1m'
csv_delimiter = ';'
csv_quotechar = '"'
csv_timezone = timezone('America/New_York')
db_filename = 'dax.db'
db_timezone = timezone('Europe/Berlin')

# Open/Create database
db = Database()

# Data Model
class Candlestick(db.Entity):
    timeframe = Required(unicode)
    timestamp = Required(datetime)
    open = Required(Decimal, precision=12, scale=6)
    high = Required(Decimal, precision=12, scale=6)
    low = Required(Decimal, precision=12, scale=6)
    close = Required(Decimal, precision=12, scale=6)
    volume = Required(Decimal, precision=12, scale=6)

db.bind(provider='sqlite', filename=db_filename, create_db=True)
db.generate_mapping(create_tables=True)    

# Loader class
class Loader():
    def load(self):
        rowcount = 0;
        current_year = -1;
        current_month = -1;
        with open(csv_filename, newline='') as csvfile:
            r = csv.reader(csvfile, delimiter=csv_delimiter, quotechar=csv_quotechar)
            with db_session:
                for row in r:

                    _year = int(row[0][-4:])
                    _month = int(row[0][3:-5])
                    _day = int(row[0][:2])
                    _hour = int(row[1][:2])
                    _minute = int(row[1][3:5])
                    csv_dt = datetime(_year, _month, _day, _hour, _minute)
                    db_dt = csv_timezone.localize(csv_dt).astimezone(db_timezone)

                    Candlestick(
                        timeframe=db_timezone.zone, 
                        timestamp=db_dt,
                        open=row[2], 
                        high=row[3],
                        low=row[4], 
                        close=row[5],
                        volume=row[6]
                    )

                    rowcount+=1

                    if(_year != current_year or _month != current_month):
                        db.commit()
                        current_year = _year
                        current_month = _month
                        print('Loading data for ' + str(current_year) + ' ' + str(current_month) + ' ...')
                        print('Loaded ' + str(rowcount) + ' registers.')

ldr=Loader()
ldr.load();

【问题讨论】:

    标签: python sqlite memory-leaks orm ponyorm


    【解决方案1】:

    这里没有内存泄漏。 Pony 在离开 db_session 范围时清除缓存 在这里你可以看到更多信息 https://docs.ponyorm.com/transactions.html#working-with-db-session.

    尤其是这个:

    当会话结束时,它会执行以下操作:

    • 清除身份映射缓存

    您需要缩小 db_session 的范围。 另一种选择是在创建 N 个对象后执行 commit(),然后执行 rollback() 以清除缓存:

    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
    

    在此处查看有关 rollback() 发生的更多信息:https://docs.ponyorm.com/transactions.html#db-session-cache

    【讨论】:

      猜你喜欢
      • 2011-12-13
      • 2010-09-26
      • 2013-07-04
      • 2014-05-06
      • 2023-03-18
      • 1970-01-01
      • 2018-03-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多