如何将numpy数组转换为PostgreSQL列表

4

我正在尝试使用Python将numpy数组的2列作为两个数组插入到PostgreSQL表中。

PostgreSQL表是DOS: primary_key energy integer[] dos integer[]

我有一个numpy数组,它是一个2x1D数组的2D数组:

finArray = np.array([energy,dos])

我试着使用以下脚本向数据库插入数据,但是插入时一直出现错误。我无法弄清楚如何格式化数组,使其正确格式化为:INSERT INTO dos VALUES(1,'{1,2,3}','{1,2,3}')"

脚本:

import psycopg2
import argparse
import sys
import re
import numpy as np
import os

con = None


try:    
    con = psycopg2.connect(database='bla', user='bla')
    cur = con.cursor()
    cur.execute("INSERT INTO dos VALUES(1,'{%s}')", [str(finArray[0:3,0].tolist())[1:-1]])
    con.commit()


except psycopg2.DatabaseError, e:
    if con:
        con.rollback()

    print 'Error %s' % e
    sys.exit(1)

finally:
    if con:
        con.close()

我无法弄明白的部分是,我会得到如下错误:

Error syntax error at or near "0.31691105000000003"
LINE 1: INSERT INTO dos VALUES(1,'{'0.31691105000000003, -300.0, -19...

我无法确定括号中那个内部的 ' ' 是从哪里来的。

从你的问题中可以看出,你有这本书《Rails 4 Test Prescriptions》。如果你不介意,能否给我一份PDF副本,让我阅读一下? - Arup Rakshit
5个回答

4

虽然来得有点晚,但还是放出来吧。

今天我试图将一个numpy数组插入Redshift。在尝试了ododf.to_sql()等方法后,我终于找到了一种速度相当快的方法(每分钟约3k行)。我不会谈论使用那些工具所遇到的问题,但下面这个简单的方法可行:

cursor = conn.cursor()

args_str = b','.join(cursor.mogrify("(%s,%s,...)", x) for x in tuple(map(tuple,np_data)))

cursor.execute("insert into table (a,b,...) VALUES "+args_str.decode("utf-8"))
cursor.commit()
cursor.close()

第二行需要根据数组的维度进行一些调整。
你可能也想检查这些答案:
  1. 从numpy数组转换为元组
  2. psycopg2中的多行插入

1
您可能拥有一个字符串数组,请尝试更改您的命令并添加astype(float),例如:
cur.execute("INSERT INTO dos VALUES(1,'{%s}')", [str(finArray[0:3,0].astype(float).tolist())[1:-1]])

1
Psycopg将会把Python列表转换成数组,因此您只需要将NumPy数组强制转换为Python列表,并将其传递给execute方法。
import psycopg2
import numpy as np

energy = [1, 2, 3]
dos = [1, 2, 3]
finArray = np.array([energy,dos])
insert = """
    insert into dos (pk, energy) values (1, %s);
;"""
conn = psycopg2.connect("host=localhost4 port=5432 dbname=cpn")
cursor = conn.cursor()
cursor.execute(insert, (list(finArray[0:3,0]),))
conn.commit()
conn.close()

1
引号出现在numpy.ndarray.tolist()中,是因为你实际上有字符串数据。如果你不想假设数据是像@Saullo Castro建议的float类型,你也可以简单地使用str(finArray[0:3,0].tolist()).replace("'","")[1:-1]来处理它们。
然而,更合适的方法是,如果你在脚本中以任何方式处理finArray中的数据并假设它们是数字,那么最好确保它们在导入数组时就被作为数字导入。 你可以通过指定例如finArray = np.array(..., dtype=np.float)来要求数组具有特定的数据类型,并向后工作,直到适当地强制执行类型。

感谢您的帮助,但我仍然遇到类似的错误。我唯一能找到并且对我有效的解决方案是创建像这样的字符串:cur.execute(str("INSERT INTO dos VALUES(1,'{%s}','{%s}',%s,0)" % (str(atomNumbers)[1:-1],str(orbitalNum)[1:-1],finArray[0,0])))在psycopg2中出现了一些警告,即使我头上顶着一枪也不应使用百分号字符串插值,因此我不确定我是否做了错事。 [链接]http://initd.org/psycopg/docs/usage.html - Coherent

0
你需要将numpy数组转换为列表,例如:
import numpy as np
import psycopg2
fecha=12
tipo=1
precau=np.array([20.35,25.34,25.36978])
conn = psycopg2.connect("dbname='DataBase' user='Administrador' host='localhost' password='pass'")
cur = conn.cursor()
#make a list
vec1=[]
for k in precau:
    vec1.append(k)
#make a query
query=cur.mogrify("""UPDATE prediccioncaudal SET fecha=%s, precaudal=%s WHERE idprecau=%s;""", (fecha,vec1,tipo))
#execute a query
cur.execute(query)
#save changes
conn.commit()
#close connection
cur.close()
conn.close()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接