2016-08-03 21 views
5

Was ist der richtige Weg, um die Werte von numpy Integer-Objekten in Datenbanken in Python 3 einzufügen? In Python 2.7 numpy numerische Datentypen einfügen sauber in SQLite, aber sie nicht in Python 3Einfügen von numpy Integer-Typen in sqlite mit python3

import numpy as np 
import sqlite3 
conn = sqlite3.connect(":memory:") 
conn.execute("CREATE TABLE foo (id INTEGER NOT NULL, primary key (id))") 
conn.execute("insert into foo values(?)", (np.int64(100),)) # <-- Fails in 3 

Die np.float Typen scheinen sowohl in 2 und 3.

conn.execute("insert into foo values(?)", (np.float64(101),)) 

noch gut funktionieren In Python 2 sind die numpy skalaren Integer-Datentypen keine Instanzen von int mehr und konvertieren sogar ganzzahlige Fließkommazahlen in ints.

isinstance(np.int64(1), int) # <- true for 2, false for python 3 

Aus diesem Grund funktioniert das dbapi nicht mehr nahtlos mit numpy?

+0

A numpy Integer-Typ ist nicht nur die Byte-Darstellung der Zahl (es ist '.item()' Wert);: Sie sollten etwas tun ist ein Objekt, fast das gleiche wie ein einzelnes Element, 0d, Array. Ich glaube also nicht, dass Sie es in all seiner Pracht in einer Datenbank speichern können. Sie könnten den ganzzahligen Wert oder ein paar Byte-Äquivalent speichern, aber nicht das vollständige numpige Objekt. Gibt es in 'sqlite3' etwas zum Speichern einer benutzerdefinierten Objektinstanz? – hpaulj

+0

Es gibt immer den beängstigenden Pickle-Ansatz (Targeting-Typ TEXT), oder etwas moderneres und binär-basiertes wie [MessagePack] (http://msgpack.org/) (Targeting BLOB-Typ). – sascha

+0

Welchen Vorteil hat 'np.int64 (100)' anstelle von '100'? Gibt es einige nützliche Informationen, die Sie während eines Abrufs nicht wiederherstellen konnten? Sie können sehen, wie Module wie SQLAlchemy die sql-Objektschnittstelle handhaben. – hpaulj

Antwort

4

Nach sqlite3 docs:

Um andere Python-Typen mit SQLite zu verwenden, können Sie sie in einem der sqlite3 Moduls unterstützten Typen für SQLite anpassen müssen: eine von NoneType, int, float, str, Bytes.

So können Sie np.int64 Typ anzupassen.

import numpy as np 
import sqlite3 

sqlite3.register_adapter(np.int64, lambda val: int(val)) 
conn = sqlite3.connect(":memory:") 
conn.execute("CREATE TABLE foo (id INTEGER NOT NULL, primary key (id))") 
conn.execute("insert into foo values(?)", (np.int64(100),)) 

Docs