Как адаптировать новые типы Python к синтаксису SQL в python3 - PullRequest
0 голосов
/ 01 июня 2019

Я пытаюсь выяснить, как вставить составные типы данных в postgresql из python3 с помощью psycopg2.В этом я следую примеру из документации psycopg2 :

>>> from psycopg2.extensions import adapt, register_adapter, AsIs

>>> class Point(object):
...    def __init__(self, x, y):
...        self.x = x
...        self.y = y

>>> def adapt_point(point):
...     x = adapt(point.x).getquoted()
...     y = adapt(point.y).getquoted()
...     return AsIs("'(%s, %s)'" % (x, y))

>>> register_adapter(Point, adapt_point)

>>> cur.execute("INSERT INTO atable (apoint) VALUES (%s)",
...             (Point(1.23, 4.56),))

Но полученная команда sql неверна:

psycopg2.ProgrammingError: syntax error at or near "1.23"
LINE 1: INSERT INTO atable (apoint) VALUES ('(b'1.23', b'4.56')')

Как мне изменитьпример, чтобы заставить psycopg2 производить правильную команду sql?

INSERT INTO atable (apoint) VALUES ('(1.23, 4.56)');

1 Ответ

1 голос
/ 03 июня 2019

Вам необходимо декодировать значения x / y в строки, они являются байтовыми значениями (визуально отмечены префиксом b). Это фундаментальное изменение между Python2 и Python3.

class Point(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

def adapt_point(point):
    x = adapt(point.x).getquoted().decode('utf-8')
    y = adapt(point.y).getquoted().decode('utf-8')
    return AsIs("'(%s, %s)'" % (x, y))

register_adapter(Point, adapt_point)
p = Point(1.23, 4.56)
print (cur.mogrify("INSERT INTO atable (apoint) VALUES (%s)", (p,)))

возвращается:

b"INSERT INTO atable (apoint) VALUES ('(1.23, 4.56)')"
...