У меня есть следующий код, который загружает большой файл CSV (более 3,5 миллионов строк) в базу данных SQLite.
Программа работает нормально, но кажется, что она не освобождает память, поэтому во время работы программыС помощью команды top
я вижу, как увеличивается объем ее памяти до тех пор, пока она не исчерпает всю доступную серверную память и программа не будет уничтожена без вставки всех строк.
Насколько я понимаю, включается db.commit()
(который выполняется каждый размы начинаем загружать новый месяц в CSV) освобождаем любые созданные экземпляры Candlestick (которые, я полагаю, являются теми, которые заставляют память расти), но это не делает этого.
Почему это происходит и что можно исправить в коде, чтобы он работал без утечки памяти?
# -*- 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();