Python'ndarray'无法转换为MySQL类型

时间:2017-02-12 21:24:07

标签: python mysql numpy netcdf4

我试图使用python脚本在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数据库中的字段/列名称。我试图将netCDF4数据插入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)

或者如果我尝试将所有变量组合在一起

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,))

当我打印netCDF变量数据时,例如时间变量,它看起来像 此

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 

然后我只在列表中获得第一个列表而不是其他列表,我猜这是我的主要问题。

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

如果我尝试执行cursor.executemany(smeData,(v,))命令,它会给我这个错误

mysql.connector.errors.ProgrammingError: Not all parameters were used in 
the SQL statement

我的MYSQL插入语法是  我的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中 我是编程新手,我正在学习。如果有人帮助我或提供一些提示,我该如何处理这样的错误。我将非常感激。 非常感谢。

1 个答案:

答案 0 :(得分:1)

使用sqlite3而不是MYSQL,但我认为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&#39;行&#39;,3&#39;列&#39;

In [716]: data = np.arange(12).reshape(4,3)
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11]])

tolist将其转换为数字列表列表:

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>

用以下方法测试插入物:

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)

因此,它已将data.tolist()的每个子列表写为表中的记录。

我猜你想要写5个字段到数据库,对应于每个data1的{​​{1}},data2等。

要获得更多帮助,我建议包含Dataset命令,仅使用一个create进行测试,并显示(或sumarize)您要插入的Dataset

创建兼容的列表列表的另一种方法是:

dataarray

mysql.connector.errors.ProgrammingError: Failed processing format-parameters;Python 'list' cannot be converted to a MySQL type中,您试图保存5个列表的列表,每个子列表长2000个项目。让我们展开我的榜样。

我有(3,10)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) 数组

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]]) 会创建一个包含10个元素子列表的3元素列表。

data.tolist()

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. 给出了与MYSQL不同的错误,但我认为基本问题是相同的 - 试图将10个元素列表或元组写入3个字段记录。

但如果我首先转置数组,我会得到10个子列表的列表

sqlite3

转置列表是:

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)

一个众所周知的Python习惯用于转置&#39;列表使用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)]