2014-05-09 62 views
1

我正在尝试使用python将两列numpy数组作为两个数组插入到postgresql表中。如何将numpy数组转换为postgresql列表

PostgreSQL表是DOS: primary_key 能量整数[] DOS整数[]

我有一个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... 

我无法弄清楚内部''是从哪里来的。

+0

[从你的问题(http://stackoverflow.com/questions/26965937/rspec-refactoring -model-issue-from-rails-test-prescriptions-4),看起来你有[书](https://pragprog.com/book/nrtest2/rails-4-test-prescriptions)。如果你不介意,你会给我一个pdf副本吗? –

回答

1

你可能有一个字符串数组,试着改变你的命令添加astype(float),如:

cur.execute("INSERT INTO dos VALUES(1,'{%s}')", [str(finArray[0:3,0].astype(float).tolist())[1:-1]]) 
1

的报价来到了numpy.ndarray.tolist()期间来,因为你确实有一个字符串。如果你不想假设数据是float,按@Saullo Castro建议你也可以做一个简单的str(finArray[0:3,0].tolist()).replace("'","")[1:-1]来摆脱它们。

但是,更恰当的是,如果您在脚本中以任何方式处理finArray中的数据,并假定它们是数字,则应该确保将它们作为数字导入到数组中。 您可以通过指定数组类型来要求数组具有某种数据类型。 finArray = np.array(..., dtype=np.float),然后向后朝向适合执行该类型的位置。

+0

感谢您对此的帮助,但我仍然收到类似的错误。我能找到的唯一解决方案就是创建一个如下所示的字符串: 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

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() 
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() 
2

太晚了,但反正这样做了。

我试图今天插入一个numpy数组到红移。在尝试odo,df.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.close() 
flexprobi_conn.commit() 
flexprobi_conn.close() 

第二行需要根据您的阵列的尺寸做一些工作。

您可能要过检查这些答案:

  1. Converting from numpy array to tuple
  2. Multiple row inserts in psycopg2