to_sql + sqlalchemy +从+ postgresql引擎复制?

时间:2014-06-06 14:48:58

标签: pandas

我正在测试pandas dataframe的to_sql方法。

to_sql使用的是insert sql方法,这比从sql方法复制的速度慢。

我可以使用sqlalchemy和postgresql(psycopg2)引擎从to_sql中选择sql方法的副本吗?

谢谢大家的时间。

2 个答案:

答案 0 :(得分:0)

你是正确to_sql通过sqlalchemy使用INSERT INTO(发生这种情况的代码是here),因此无法使用COPY FROM使用to_sql

但是如果你需要这个,你当然可以使用它自己实现to_sql。如果您认为它具有比当前实现更好的性能和相同的功能,您可以随时向pandas发送贡献(https://github.com/pydata/pandas/blob/master/CONTRIBUTING.md)。

但是,据我所知,如果你想以"COPY table FROM file"执行SQL语句,你总是可以使用postgres引擎的execute命令。

答案 1 :(得分:0)

这不是真的。您可以通过为COPY FROM接受的kwarg method提供自己的功能,来实现此功能以使用to_sqlDataFrame.to_sql的Pandas文档中的关键之处在于,method不仅可以是字符串,而且可以是可调用的。那就是你将提供的

例如:

from csv import (writer as csv_writer, QUOTE_MINIMAL)
from io import StringIO

def some_function(df, connection):        
    try:
        frame.to_sql(
            'my_table',
            connection,
            schema='public',
            if_exists='append',
            index=False,
            method=copy_from_method)
    except Exception as err:
        print('Got an error ({})'.format(str(err))

然后,您可以像这样实现copy_from_method

def copy_from_method(table, conn, keys, data_iter, pre_truncate=False, fatal_failure=False):
    "Custom method for pandas.DataFrame.to_sql that will use COPY FROM"""

    dbapi_conn = conn.connection
    cur = dbapi_conn.cursor()

    s_buf = StringIO()
    writer = csv_writer(s_buf, quoting=QUOTE_MINIMAL)
    writer.writerows(data_iter)
    s_buf.seek(0)

    columns = ', '.join('"{}"'.format(k) for k in keys)
    table_name = '{}.{}'.format(
        table.schema, table.name) if table.schema else table.name

    sql_query = 'COPY %s (%s) FROM STDIN WITH CSV' % (table_name, columns)
    cur.copy_expert(sql=sql_query, file=s_buf)
    return cur.rowcount

示例copy_from_method显然可能需要做一些工作-在某些情况下,在使用CSV编写器进行引用和转义时,您需要格外小心。但是这个粗糙的版本应该可以很好地工作,除非出现任何错别字/复制粘贴错误(这是我在项目中使用的精简版本)