Заклинатель типа psycopg2 создан и зарегистрирован, но не найден - PullRequest
0 голосов
/ 24 сентября 2018

Я пытаюсь просто использовать числа с плавающей запятой вместо десятичных в psycopg2, как описано в FAQ .Я не могу заставить psycopg2 использовать кастера кастомного типа.

import psycopg2

psycopg2.extensions.DECIMAL.values   # Out: (1700,)
psycopg2.extensions.string_types[1700]   # Out: <psycopg2._psycopg.type 'DECIMAL' at 0x1104842c8>

Есть заклинатель старого типа.Давайте создадим новый:

# Directly from documentation
DEC2FLOAT = psycopg2.extensions.new_type(
    psycopg2.extensions.DECIMAL.values,
    'DEC2FLOAT',
    lambda value, curs: float(value) if value is not None else None)
psycopg2.extensions.register_type(DEC2FLOAT)

psycopg2.extensions.string_types[1700]   # Out: <psycopg2._psycopg.type 'DEC2FLOAT' at 0x110435d18>

Хорошо, новый находится в поле зрения кастеров.Давайте попробуем использовать это:

conn = psycopg2.connect(dbname='test')
cur = conn.cursor()

cur.execute('SELECT NULL::DEC2FLOAT')
---------------------------------------------------------------------------
ProgrammingError                          Traceback (most recent call last)
<ipython-input-10-04a1f82b3b07> in <module>()
----> 1 cur.execute('SELECT NULL::DEC2FLOAT')

ProgrammingError: type "dec2float" does not exist
LINE 1: SELECT NULL::DEC2FLOAT
                     ^

Не найдено.Итак, давайте посмотрим, есть ли еще старый заклинатель типа DECIMAL:

conn.rollback()
cur.execute('SELECT NULL::DECIMAL') # original caster works still...

psycopg2.extensions.string_types[1700]   # Out: [<psycopg2._psycopg.type 'DEC2FLOAT' at 0x110435d18>

Я не уверен, что я делаю не так, тем более, что он в основном из документов .Я попытался изменить объем вызова register_type.Я попытался сопоставить регистр имени типа заклинателя.Я попытался изменить порядок вызовов register_type и вызовов conn / cursor.Есть идеи?

1 Ответ

0 голосов
/ 25 сентября 2018

Вы зарегистрировали адаптер, а не новый тип в Postgres.Адаптер автоматически преобразует decimal в float.Попробуйте это:

cur.execute("select 1.23")
row = cur.fetchone()
print(row[0], type(row[0]))

# output: 1.23 <class 'decimal.Decimal'>

DEC2FLOAT = psycopg2.extensions.new_type(
    psycopg2.extensions.DECIMAL.values,
    'DEC2FLOAT',
    lambda value, curs: float(value) if value is not None else None)
psycopg2.extensions.register_type(DEC2FLOAT)

cur.execute("select 1.23")
row = cur.fetchone()
print(row[0], type(row[0]))

# output: 1.23 <class 'float'>
...