2017-02-12 4 views
1

python 스크립트를 사용하여 MYSQL 데이터베이스에 일부 데이터를 저장하려고하는데 다음 오류가 발생합니다.Python 'ndarray'를 MySQL 유형으로 변환 할 수 없습니다.

mysql.connector.errors.ProgrammingError: Failed processing format-parameters; 
Python 'ndarray' cannot be converted to a MySQL type 

실제로 netCDF 파일에서 변수를 추출하고 MYSQL db에 저장하려고합니다. 내 코드는

import sys 
import collections 
import os 
import netCDF4 
import calendar 
from netCDF4 import Dataset 
import mysql.connector 
from mysql.connector import errorcode 

table = 'rob-tabl' 
con = mysql.connector.connect(user='rob', password='xxxx', 
            database=roby) 
cursor = con.cursor() 


smeData = """ 
     CREATE TABLE rob-tabl (
     `id` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY, 
     `time.val` double, 
     `time.microsec` double, 
     `temp.degrees` double, 
     `humid.calc` double, 
     `pressure.calc` double;""" 

이들은 mMYSQL 데이터베이스의 내 필드/열 이름입니다. 나는 MYSQL에

smeData = "INSERT INTO `" + table + "` " 
. 
. 
. 
. 
. 
. 
. 
. 

data_array = [] 
for item in totfiles.items(): # loop on different netCDF files in a      directory , but at the moment I had only one file 
    nc = Dataset('filename', 'r') 
    data1 = nc.variables['time'][:] 
    data2 = nc.variables['microsec'][:] 
    data3 = nc.variables['temperature'][:] 
    data4 = nc.variables['humidity'][:] 
    data5 = nc.variables['pressure'][:] 
    data = data1 + data2 + data3 + data4 + data5 
    data_array.append(data) 
    print 'data_array: ', data_array 
    cursor.execute(smeData, data_array) 

을 netCDF4 데이터를 삽입하려고 또는 내가 netCDF의 변수 데이터를 인쇄 할 때이

data_array = [] 
for item in totfiles.items(): 
    nc = Dataset('filename', 'r') 
    data1 = nc.variables['time'][:] 
    data2 = nc.variables['microsec'][:] 
    data3 = nc.variables['temperature'][:] 
    data4 = nc.variables['humidity'][:] 
    data5 = nc.variables['pressure'][:] 
    data = ([(data1).tolist(), (data2).tolist(), data3.tolist(), data4.tolist(), data5.tolist()]) 
    data_array.append(data) 
    print type(data) 
    for v in data: 
     cursor.executemany(smeData, (v,)) 

처럼 모든 변수를 결합하려고하면, 예를 들어, 시간 변수, 그것은 이

처럼 보인다
nc.variables['time'][:] # netCDF variable 

내가이

[1302614127 1302614137 1302614147 ..., 1302614627 1302614647 1302614657] 
있어

및 마이크로은

[0 0 0 ..., 0 0 0] 

같은 외모와 data_array는

data_array= [[1302614127 1302614137 1302614147 ..., 1302614627 1302614647 
1302614657], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [21, 22,34,34....,67,55], [12.2, 12.54, 12.55....,45.54,45.48], [0,0,0...,0,0,00]] 

처럼 보이지만 내가

for v in data: 
    print v 

를 인쇄하면 다음 난 단지 목록 내 첫번째 목록을 가지고 아닌 다른리스트 나는 내 주요 이슈라고 생각한다. 내가 cursor.executemany (smeData, (V)) 명령을 수행하려고하면, 그것은 나에게이 오류

내 MYSQL 구문을 삽입은

mysql.connector.errors.ProgrammingError: Not all parameters were used in 
the SQL statement 
를 제공하고

[1302614127 1302614137 1302614147 ..., 1302614627 1302614647 1302614657] 

는 내 MYSQL 구문은

입니다
"INSERT INTO `rob-tabl` (`time.val`,`time.microsec`,`temp.degrees`, 
`humid.calc`,`pressure.calc`) VALUES (%s,%s,%s,%s,%s)" 

제 경우에는 numpy.float32입니다. MYSQL에 5 개의 열을 만들었고 netCDF의 데이터를 db에 저장해야했습니다.
저는 프로그래밍에 익숙하지 않고 배우고 있습니다. 누군가가 나를 도와 주거나 그런 실수를 어떻게 처리 할 수 ​​있는지 알려주십시오. 나는 매우 감사 할 것이다. 많이 고맙습니다.

+0

는 종종 사람들 (예를 들어'pickle','np.save'로) 문자열로 배열을 인코딩하고 데이터베이스에 그것을 저장 'BLOB'로 하지만 숫자 필드 열로 배열을 저장하려고하는 것 같습니다. 1d 배열을 단순한리스트로 변환하기 위해서'arr.tolist()'를 해봤습니까? – hpaulj

+0

MYSQL 필드 정의의 샘플을 제공하십시오. – hpaulj

+0

@hpaulj 도움을 주셔서 대단히 감사합니다. MYSQL 필드 샘플을 추가하고 곧 다시 올 것입니다. 네, 데이터베이스에 5 개의 필드를 쓰려고합니다. 더 자세한 내용으로 내 질문을 업데이트 할 것입니다. – rob

답변

1

오히려 MYSQL보다는 sqlite3 작업,하지만 난 SQL이

In [709]: import sqlite3 
In [711]: conn=sqlite3.connect(":memory:") 

간단한 3 필드 테이블 정의와 유사합니다 생각 :

In [714]: conn.execute('create table test (x, y, z)') 
Out[714]: <sqlite3.Cursor at 0xa943cb20> 

는 NumPy와 배열, 4 '행'을 정의를, 3 '열'

tolist은 마비 목록으로 변환됩니다. ERS :

In [735]: data.tolist() 
Out[735]: [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]] 

나는 함께 테이블에 삽입 할 수 있습니다

In [719]: conn.executemany('insert into test values (?,?,?)',data.tolist()) 
Out[719]: <sqlite3.Cursor at 0xa93dfae0> 

와 함께 삽입 테스트 : 레코드의로가 작성했습니다 data.tolist()의 각 하위 목록을 그래서

In [720]: for row in conn.execute('select x,y,z from test'): 
    ...:  print(row) 
    ...:  
(0, 1, 2) 
(3, 4, 5) 
(6, 7, 8) 
(9, 10, 11) 

을 탁자.

data1, data2 등 각 Dataset 등등에 해당하는 5 개의 필드를 데이터베이스에 쓰고 싶습니다.

더 내가 한 Datasetcreate 명령, 테스트 포함 좋을 것 도움말 및 쇼 (또는 sumarize) 삽입하려고하는 dataarray를 얻으려면.

목록의 호환 목록을 작성하는 또 다른 방법은 다음과 같습니다 mysql.connector.errors.ProgrammingError: Failed processing format-parameters;Python 'list' cannot be converted to a MySQL type에서

In [736]: data = [np.arange(3).tolist(),np.arange(10,13).tolist(),np.arange(20,23).tolist()] 
In [737]: data 
Out[737]: [[0, 1, 2], [10, 11, 12], [20, 21, 22]] 
In [738]: conn.executemany('insert into test values (?,?,?)',data) 
Out[738]: <sqlite3.Cursor at 0xa93df320> 
In [739]: for row in conn.execute('select x,y,z from test'): 
    ...:  print(row) 
    ...:  
.... 
(0, 1, 2) 
(10, 11, 12) 
(20, 21, 22) 

당신은 5 개 목록의 목록, 2000 개 항목 긴 각 하위 목록을 저장하기 위해 노력하고 있습니다. 내보기를 확장 할 수 있습니다.

난 (3,10) data 배열

In [881]: data 
Out[881]: 
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 
     [ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], 
     [100, 101, 102, 103, 104, 105, 106, 107, 108, 109]]) 

data.tolist() 10 개 엘리먼트 하위 목록으로 3 요소 목록을 가질 것이다.

In [884]: conn.executemany('insert into test values (?,?,?)',data.tolist()) 
--------------------------------------------------------------------------- 
ProgrammingError       Traceback (most recent call last) 
<ipython-input-884-6788d19a96ab> in <module>() 
----> 1 conn.executemany('insert into test values (?,?,?)',data.tolist()) 

ProgrammingError: Incorrect number of bindings supplied. The current statement uses 3, and there are 10 supplied. 

sqlite3은 MYSQL보다 다른 오류를주고있다,하지만 근본적인 문제는 같은 생각 - 그 3 필드 레코드에 10 요소 목록 또는 튜플을 작성하려고의. 내가 먼저 배열을 바꾸어 경우

는하지만, 10 개 하위 목록

의 목록을
In [885]: conn.executemany('insert into test values (?,?,?)',data.T.tolist()) 
Out[885]: <sqlite3.Cursor at 0xa6c850a0> 
In [886]: for row in conn.execute('select x,y,z from test'): 
    ...:  print(row) 
.... 
(0, 10, 100) 
(1, 11, 101) 
(2, 12, 102) 
(3, 13, 103) 
(4, 14, 104) 
(5, 15, 105) 
(6, 16, 106) 
(7, 17, 107) 
(8, 18, 108) 
(9, 19, 109) 

전치 목록은 다음과 같습니다

In [887]: data.T.tolist() 
Out[887]: 
[[0, 10, 100], 
[1, 11, 101], 
... 
[9, 19, 109]] 

'전치'목록에 대한 잘 알려진 파이썬 관용구는 zip를 사용 . 사실 튜플 목록을 생성하는데 이는 좋은 것일 수 있습니다.

In [888]: list(zip(*data)) 
Out[888]: 
[(0, 10, 100), 
(1, 11, 101), 
(2, 12, 102), 
.... 
(8, 18, 108), 
(9, 19, 109)] 

튜플의리스트 형식으로 쉽게 :

for row in data.T.tolist(): 
    print('%s,%s,%s'%tuple(row)) 
for row in zip(*data): 
    print('%s,%s,%s'%row) 
+0

도움을 주셔서 대단히 감사합니다. 그것은 완벽하게 잘 작동하고 내 필요에 따라. – rob

+0

미안하지만 작은 질문이 하나 있습니다. tolist()는 잘 작동하지만 목록이 5 개있는 경우 withoin 목록에 "모든 매개 변수가 SQL 문 에 사용되지 않았습니다."라는 문항이 있고 내 질문이 업데이트되었습니다. 나에게 작은 단서를 줄 수 있다면, 나는 정말로 감사 할 것이고, 그것은 나의 날을 구할 것이다. 아니면 새로운 질문으로 게시해야합니까? – rob

+0

데이터가 다 잘 될 때까지는 이해할 수 없지만 cursor.execute를 사용하여 저장하려고하면 문제가 발생합니다. MYSQL 명령에 문제가 있습니다. 단일 변수를 삽입하려고하면 잘되지만 여러 변수를 저장하면이 오류가 발생합니다. – rob