繁体   English   中英

Python:读取超过1M的小型csv文件并写入数据库

[英]Python: reading over 1M small csv files and writing to a db

我有超过百万次的快照文件,我需要合并并创建一个文件/数据库进行分析。

我尝试在下面的代码中执行此操作。 首先,我从一个URL列表中读取一个小的csv,需要几列,从文本到日期解析日期字段并将其写入sqlite数据库。

虽然这段代码在一小部分文件中运行良好,但迭代超过一百万个CSV的速度太慢。

我不确定如何提高性能,甚至不确定Python是否适合这项工作。 任何帮助改进此代码或建议将不胜感激。

import pandas as pd
from sqlalchemy import create_engine
import datetime
import requests
import csv
import io

csv_database2 = create_engine('sqlite:///csv_database_test.db')

col_num = [0,8,9,12,27,31]

with open('url.csv','r') as line_list:
     reader = csv.DictReader(line_list,)

for line in reader:

    data = requests.get(line['URL'])
    df = pd.read_csv(io.StringIO(data.text), usecols=col_num, infer_datetime_format=True)
    df.columns.values[0] = 'DateTime'
    df['ParseDateTime'] = [datetime.datetime.strptime(t, "%a %b %d %H:%M:%S %Y") for t in df.DateTime]
    df.to_sql('LineList', csv_database2, if_exists='append')

恕我直言python非常适合这项任务,通过简单的修改,您可以实现您想要的性能。

AFAICS可能存在两个影响性能的瓶颈:

下载网址

你一次下载一个文件,如果下载一个文件需要0.2秒下载1M文件,它将需要> 2天! 我建议您使用concurrent.futures并行下载示例代码:

from concurrent.futures import ThreadPoolExecutor
import requests


def insert_url(line):
    """download single csv url and insert it to SQLite"""
    data = requests.get(line['URL'])
    df = pd.read_csv(io.StringIO(data.text), usecols=col_num,
                     infer_datetime_format=True)
    df.columns.values[0] = 'DateTime'
    df['ParseDateTime'] = [
        datetime.datetime.strptime(t, "%a %b %d %H:%M:%S %Y") for t in
        df.DateTime]
    df.to_sql('LineList', csv_database2, if_exists='append')


with ThreadPoolExecutor(max_workers=128) as pool:
    pool.map(insert_url, lines)

插入SQL

试着看一下如何在这个 SO答案中优化SQL插入。

进一步指导

  • 我会从并行请求开始,因为它似乎是更大的瓶颈
  • 运行探查器以更好地了解代码在大多数情况下花费的时间

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM