将 1100 万行从 Postgresql 导入到 Pandas/Python

Posted

技术标签:

【中文标题】将 1100 万行从 Postgresql 导入到 Pandas/Python【英文标题】:Importing 11 million rows from Postgresql to Pandas/Python 【发布时间】:2020-04-02 16:40:25 【问题描述】:

我正在尝试从托管在 AWS 服务器上的 PostgreSQL 数据库中加载 1100 万条记录。我尝试使用 pandas read_sql,并在 4 小时内得到结果。我的笔记本电脑上有 32 GB 的 RAM,还有第 7 代 Core i7。我也将块大小设置为 10000,但它并没有改善疯狂时间。我在网上查看了许多文章,并尝试了所有文章,但没有一篇能加快我的进程。如果可能的话,我希望理想地在 20 分钟内加载这些数据,或者尽可能短的时间。我需要数据框中的这些数据,以便我可以与我拥有的其他文件进行一些合并,如果我可以在 Python 中获取数据,我可以自动化我的过程。我的代码如下所示:

from io import StringIO
import psycopg2
import psycopg2.sql as sql
import pandas as pd
import numpy as np
import time


connection = psycopg2.connect(user="abc",
                                      password="efg",
                                      host="123.amazonaws.com",
                                      port="5432",
                                      database="db")

date='2020-03-01'
columns= '"LastName","FirstName","DateOfBirth","PatientGender","Key"'

postgreSQL_select_Query = 'select ' +  columns + ' from "Table" where "CreatedDate"::date>=' + "'" + date + "'" + 'limit 11000000'


x=pd.read_sql_query(postgreSQL_select_Query, connection, index_col=None, coerce_float=True, params=None, parse_dates=None, chunksize=10000)

请建议我可以做些什么来改进此代码并减少运行时间。

我还附加了另一个代码段,我正在使用它来执行此操作,但结果与它在 HOURS 中获取行的结果相同。任何指导将不胜感激。

第二种方法:

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

@author: ssullah
"""
from io import StringIO
import psycopg2
import psycopg2.sql as sql
import pandas as pd
import numpy as np
import time

start = time.time()
print("Started")

#Retreiving records from DB
def getdata():  
    try:
        start = time.time()
        print("Started")
        connection = psycopg2.connect(user="a"
                                      password="as",
                                      host="aws",
                                      port="5432",
                                      database="as")


        cur= connection.cursor()

        date='2020-03-01'
        columns= '"LastName","FirstName","DateOfBirth","PatientGender","Key"'

        postgreSQL_select_Query = 'select ' +  columns + ' from "ALLADTS" where "CreatedDate"::date>=' + "'" + date + "'" + 'limit 11000000'

        cur = connection.cursor('cursor-name') # server side cursor
        cur.itersize = 10000 # how much records to buffer on a client
        cur.execute(postgreSQL_select_Query)

        mobile_records = cur.fetchall() 


    #Column names as per schema, defined above
        col_names=["LastName","FirstName","DateOfBirth","PatientGender","Key"]

    # Create the dataframe, passing in the list of col_names extracted from the description
        records = pd.DataFrame(mobile_records,col_names)

        return records;


    except (Exception, psycopg2.Error) as error :
        print ("Error while fetching data from PostgreSQL", error)

    finally:
        #closing database connection.
        if(connection):
            cursor.close()
            connection.close()
            print("PostgreSQL connection is closed")


records=getdata()
end = time.time()
print("The total time:", (end - start)/60, 'minutes')

【问题讨论】:

您可以尝试使用命令行psql 将相同的数据检索到文本文件中吗?如果需要相同的时间,那么 pandas 或 Python 不在问题的范围内,问题只是检索数据的时间。 在将数据导入 pandas 之前,您是否无法在 POSTGRES 中汇总数据? 我可以考虑使用 psql 将其导出到文本文件中,如果您对此有任何参考,那就太好了。 WombatPM:我们在 potgres 中谈论什么样的总结?我已经只从表中取出 4 列,因此数据的大小更小。 参见 \copy 命令,postgresql.org/docs/current/…。您可能希望使用命令的\copy (<your query here>) to <filename> 形式。在 Linux 上,如果您只想从远程服务器获取数据而不实际保存,则可以使用 /dev/null 作为文件名。 【参考方案1】:

更新:

我决定使用 Python 在 postgresql 中创建一个临时表,并将新文件从 pandas 加载到 Postgresql,而不是在 Python 中加载数据。使用 python 中的查询填充表后,我就能够查询并获得所需的输出 a 作为 panda 数据框中的最终结果。

所有这些都花了 1.4 分钟,而在 Pgadmin 中运行相同的查询需要 30 分钟,因此通过利用 Python,并使用用 Python 编写的 sql 查询进行计算,我能够以指数方式加速该过程,并且在同时不必处理我记忆中的1100万条记录。谢谢你的建议。

【讨论】:

我不明白将新文件从 pandas 加载到 postgres。如果可能,请您提供一个代码 sn-p 吗?

以上是关于将 1100 万行从 Postgresql 导入到 Pandas/Python的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL大表的更新时间

百万行超大csv如何快速导入mysql

1100亿行代码!华为是如何管理的?

将文件从 PostgreSQL 导入到 R

使用 heroku pg:backups:restore 导入 Heroku Postgres

带有 pg8000 的 PostgreSQL - 从 SQL 插入结果到另一个表