【问题标题】:to_sql + sqlalchemy + copy from + postgresql engine?to_sql + sqlalchemy + 从 + postgresql 引擎复制?
【发布时间】:2014-07-27 21:27:09
【问题描述】:

我正在测试 pandas DataFrameto_sql 方法。

to_sql 正在使用INSERT SQL 方法,这比COPY FROM SQL 方法慢。

我可以选择to_sql 使用的COPY FROM SQL 方法,使用 SQLAlchemy 和 Postgresql (psycopg2) 引擎吗?

【问题讨论】:

标签: python pandas postgresql sqlalchemy


【解决方案1】:

这并不完全正确。您可以通过为 to_sql 接受的 kwarg method 提供自己的函数来实现此功能以使用 COPY FROMDataFrame.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 编写器。但是这个粗略的版本应该工作得比较好,除非有任何拼写错误/复制粘贴错误(这是我在项目中使用的精简版本)

【讨论】:

    【解决方案2】:

    你是正确的 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 命令。

    【讨论】:

      猜你喜欢
      • 2012-10-18
      • 2014-09-12
      • 2018-10-04
      • 1970-01-01
      • 2015-06-03
      • 1970-01-01
      • 1970-01-01
      • 2023-01-24
      • 1970-01-01
      相关资源
      最近更新 更多