【问题标题】:Psycopg2 "copy_from" command, possible to ignore delimiter in quote (getting error)?Psycopg2“copy_from”命令,可以忽略引号中的分隔符(出现错误)?
【发布时间】:2018-01-30 07:23:55
【问题描述】:

我正在尝试使用 copy_from 命令(在 postgres 中使用复制命令的功能)以类似 csv 的结构将数据行加载到 postgres 中。我的数据用逗号分隔(不幸的是,由于我不是数据所有者,我不能只更改分隔符)。当我尝试加载包含逗号的引号中的值的行时遇到问题(即,不应将逗号视为分隔符)。

比如这行数据就可以了:

",Madrid,SN,,SEN,,,SN,173,157"

这行数据不行:

","Dominican, Republic of",MC,,YUO,,,MC,65,162",

一些代码:

    conn = get_psycopg_conn()
    cur = conn.cursor()

    _io_buffer.seek(0) #This buffer is holding the csv-like data
    cur.copy_from(_io_buffer, str(table_name), sep=',', null='', columns=column_names)
    conn.commit()

【问题讨论】:

标签: python postgresql psycopg2


【解决方案1】:

It looks like copy_from doesn't expose the csv mode or quote options,其中are available form the underlying PostgreSQL COPY command。所以你需要修补 psycopg2 来添加它们,或者use copy_expert

我没试过,但是类似

curs.copy_expert("""COPY mytable FROM STDIN WITH (FORMAT CSV)""", _io_buffer)

可能就足够了。

【讨论】:

  • 感谢克雷格这回答了我的问题。不幸的是,数据在此过程中的某个地方出现了乱序,所以除非我解决了这个问题,否则将没有机会实现这一点。不过更进一步!
  • 这为我解决了问题。谢谢。遗憾的是 Psycopg2 没有内置这些​​选项。
  • @sudo 好吧,直到有人写了一个补丁来实现它才可悲。修改 psycopg2 并不太难。
【解决方案2】:

我遇到了同样的错误,并且能够根据craig-ringer 列出的单行代码接近修复。我需要的另一项是使用df.to_csv(index=False,header=False, quoting=csv.QUOTE_NONNUMERIC,sep=',') 尤其是, quoting=csv.QUOTE_NONNUMERIC 为初始对象添加引号。

从 MySQL 中提取一个数据源并将其存储在 Postgres 中的完整示例如下:

#run in python 3.6
import MySQLdb
import psycopg2
import os
from io import StringIO
import pandas as pd
import csv

mysql_db = MySQLdb.connect(host="host_address",# your host, usually localhost
                     user="user_name",         # your username
                     passwd="source_pw",  # your password
                     db="source_db")       # name of the data base

postgres_db = psycopg2.connect("host=dest_address dbname=dest_db_name user=dest_user password=dest_pw")

my_list = ['1','2','3','4']

# you must create a Cursor object. It will let you execute all the queries you need
mysql_cur = mysql_db.cursor()
postgres_cur = postgres_db.cursor()

for item in my_list:
  # Pull cbi data for each state and write it to postgres
  print(item)
  mysql_sql = 'select * from my_table t \
       where t.important_feature = \'' + item + '\';'

  # Do something to create your dataframe here...
  df = pd.read_sql_query(mysql_sql, mysql_db)

  # Initialize a string buffer
  sio = StringIO()
  sio.write(df.to_csv(index=False,header=False, quoting=csv.QUOTE_NONNUMERIC,sep=','))  # Write the Pandas DataFrame as a csv to the buffer
  sio.seek(0)  # Be sure to reset the position to the start of the stream

  # Copy the string buffer to the database, as if it were an actual file
  with postgres_db.cursor() as c:
      print(c)
      c.copy_expert("""COPY schema:new_table FROM STDIN WITH (FORMAT CSV)""", sio)
      postgres_db.commit()

mysql_db.close()
postgres_db.close()

【讨论】:

    猜你喜欢
    • 2022-01-08
    • 2015-04-11
    • 2013-08-14
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    相关资源
    最近更新 更多