psycopg2: невозможно адаптировать тип 'numpy.int64' - PullRequest
0 голосов
/ 31 мая 2018

У меня есть фрейм данных с dtypes, показанным ниже, и я хочу вставить фрейм данных в базу данных postgres, но это не удается из-за ошибки невозможно адаптировать тип 'numpy.int64'

id_code               int64
sector              object
created_date         float64
updated_date    float64

Как я могу преобразовать эти типы в нативные типы Python, такие как int64 (который по сути является «numpy.int64»), в классический int, который затем будет приемлем для postgres через клиента psycopg2.

data['id_code'].astype(np.int)  defaults to int64

Тем не менее возможно преобразование из одного типа numpy в другой (например, из int в float)

data['id_code'].astype(float)

изменяется на

dtype: float64

Нижняя линиязаключается в том, что psycopg2, похоже, не понимает тип данных numpy, если у кого-то есть идеи, как преобразовать их в классические типы, что было бы полезно.

Обновлено: вставка в DB

def insert_many():
    """Add data to the table."""
    sql_query = """INSERT INTO classification(
                id_code, sector, created_date, updated_date)
                VALUES (%s, %s, %s, %s);"""
    data = pd.read_excel(fh, sheet_name=sheetname)
    data_list = list(data.to_records())

    conn = None
    try:
        conn = psycopg2.connect(db)
        cur = conn.cursor()
        cur.executemany(sql_query, data_list)
        conn.commit()
        cur.close()
    except(Exception, psycopg2.DatabaseError) as error:
        print(error)
    finally:
        if conn is not None:
            conn.close()

Ответы [ 3 ]

0 голосов
/ 31 мая 2019

Добавьте ниже где-нибудь в вашем коде:

import numpy
from psycopg2.extensions import register_adapter, AsIs
def addapt_numpy_float64(numpy_float64):
    return AsIs(numpy_float64)
def addapt_numpy_int64(numpy_int64):
    return AsIs(numpy_int64)
register_adapter(numpy.float64, addapt_numpy_float64)
register_adapter(numpy.int64, addapt_numpy_int64)
0 голосов
/ 26 июня 2019

та же проблема здесь, успешно решить эту проблему после того, как я преобразую серии в nd.array и int.

вы можете попробовать следующим образом:

data['id_code'].values.astype(int)

-

update:

, если значение, включая NaN, все равно неверно.Кажется, что psycopg2 не может объяснить формат np.int64, поэтому следующие методы работают для меня.

import numpy as np
from psycopg2.extensions import register_adapter, AsIs
psycopg2.extensions.register_adapter(np.int64, psycopg2._psycopg.AsIs)

0 голосов
/ 31 мая 2018

Я не уверен, почему ваш data_list содержит типы данных NumPy, но то же самое происходит со мной, когда я запускаю ваш код.Вот альтернативный способ построения data_list, чтобы целые числа и числа с плавающей точкой заканчивались как их собственные типы питона:

data_list = [list(row) for row in data.itertuples(index=False)] 

Альтернативный подход

Я думаюВы можете сделать то же самое в меньшем количестве строк кода, используя pandas to_sql :

import sqlalchemy
import pandas as pd
data = pd.read_excel(fh, sheet_name=sheetname)
engine = sqlalchemy.create_engine("postgresql://username@hostname/dbname")
data.to_sql(engine, 'classification', if_exists='append', index=False)
...