如何在python3中将新的Python类型适应SQL语法

时间:2019-06-01 20:26:54

标签: python-3.x psycopg2

我试图弄清楚如何使用psycopg2将复合数据类型从python3插入到postgresql中。在此,我遵循psycopg2 documentation中的示例:

>>> 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 个答案:

答案 0 :(得分:1)

您需要将x / y值解码为字符串,它们是Byte值(在视觉上由前缀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)')"