如何在 Python 和 postgresql 中使用 inet 类型?

发布于 2024-11-08 11:41:03 字数 2120 浏览 0 评论 0原文

我正在编写一个使用 postgresql 数据库的 python3 程序,我正在使用 py-postgresql: http://python.projects .postgresql.org/ 作为数据库驱动程序。 一张表使用 inet 类型存储 IP 地址。

我创建了以下准备好的语句:

aID = db.prepare('SELECT id FROM a_records WHERE ip = $1 LIMIT 1')

当调用 aID(ip) 时,出现以下错误:

(ip 是 python 字符串)

 File "/usr/local/lib/python3.1/dist-packages/postgresql/driver/pq3.py", line
1517, in __call__
    c = SingleXactFetch(self, parameters)
  File "/usr/local/lib/python3.1/dist-packages/postgresql/driver/pq3.py", line
837, in __init__
    Output.__init__(self, '')
  File "/usr/local/lib/python3.1/dist-packages/postgresql/driver/pq3.py", line
622, in __init__
    self._init()
  File "/usr/local/lib/python3.1/dist-packages/postgresql/driver/pq3.py", line
854, in _init
    STEP()
  File "/usr/local/lib/python3.1/dist-packages/postgresql/driver/pq3.py", line
2612, in _pq_step
    self.typio.raise_error(x.error_message, cause = getattr(x, 'exception', Non
e))
  File "/usr/local/lib/python3.1/dist-packages/postgresql/driver/pq3.py", line
507, in raise_error
    self.raise_server_error(error_message, **kw)
  File "/usr/local/lib/python3.1/dist-packages/postgresql/driver/pq3.py", line
498, in raise_server_error
    raise server_error
postgresql.exceptions.BinaryRepresentationError: invalid address family in exte
rnal "inet" value
  CODE: 22P03
  LOCATION: File 'network.c', line 218, in network_recv from SERVER
RESULT:
  type: SingleXactFetch
  parameters: ('139.78.113.1',)
STATEMENT: [prepared]
  sql_parameter_types: ['pg_catalog.inet']
  results: (id INTEGER)
  statement_id: py:0x2ff9a50
  string: SELECT id FROM a_records WHERE ip = $1 LIMIT 1
CONNECTION: [idle]
  client_address: 127.0.0.1/32
  client_port: 51563
  version:
    PostgreSQL 8.4.7 on x86_64-pc-linux-gnu, compiled by GCC gcc-4.4.real (Debi
an 4.4.5-8) 4.4.5, 64-bit
CONNECTOR: [IP4] pq://python:***@127.0.0.1:5432/vdz
  category: None
DRIVER: postgresql.driver.pq3.Driver

任何人都可以帮我调试这个并找出为什么 postgresql 不喜欢 inet 数据吗?

谢谢!

I am writing a python3 program that uses a postgresql database, I am using py-postgresql: http://python.projects.postgresql.org/ as the database driver.
One table stores IP addresses using the inet type.

I have created the following prepared statement:

aID = db.prepare('SELECT id FROM a_records WHERE ip = $1 LIMIT 1')

When calling aID(ip) I get the following error:

(ip is a python string)

 File "/usr/local/lib/python3.1/dist-packages/postgresql/driver/pq3.py", line
1517, in __call__
    c = SingleXactFetch(self, parameters)
  File "/usr/local/lib/python3.1/dist-packages/postgresql/driver/pq3.py", line
837, in __init__
    Output.__init__(self, '')
  File "/usr/local/lib/python3.1/dist-packages/postgresql/driver/pq3.py", line
622, in __init__
    self._init()
  File "/usr/local/lib/python3.1/dist-packages/postgresql/driver/pq3.py", line
854, in _init
    STEP()
  File "/usr/local/lib/python3.1/dist-packages/postgresql/driver/pq3.py", line
2612, in _pq_step
    self.typio.raise_error(x.error_message, cause = getattr(x, 'exception', Non
e))
  File "/usr/local/lib/python3.1/dist-packages/postgresql/driver/pq3.py", line
507, in raise_error
    self.raise_server_error(error_message, **kw)
  File "/usr/local/lib/python3.1/dist-packages/postgresql/driver/pq3.py", line
498, in raise_server_error
    raise server_error
postgresql.exceptions.BinaryRepresentationError: invalid address family in exte
rnal "inet" value
  CODE: 22P03
  LOCATION: File 'network.c', line 218, in network_recv from SERVER
RESULT:
  type: SingleXactFetch
  parameters: ('139.78.113.1',)
STATEMENT: [prepared]
  sql_parameter_types: ['pg_catalog.inet']
  results: (id INTEGER)
  statement_id: py:0x2ff9a50
  string: SELECT id FROM a_records WHERE ip = $1 LIMIT 1
CONNECTION: [idle]
  client_address: 127.0.0.1/32
  client_port: 51563
  version:
    PostgreSQL 8.4.7 on x86_64-pc-linux-gnu, compiled by GCC gcc-4.4.real (Debi
an 4.4.5-8) 4.4.5, 64-bit
CONNECTOR: [IP4] pq://python:***@127.0.0.1:5432/vdz
  category: None
DRIVER: postgresql.driver.pq3.Driver

Can anyone help me debug this and figure out why postgresql is not liking the inet data?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

余生一个溪 2024-11-15 11:41:03

@mrlanrat,这是因为 python 库以 TEXT 数据类型发送参数,但 PostgreSQL 需要 INET 数据类型。您的示例更改了参数,以便 PostgreSQL 需要 TEXT 数据类型,然后将其转换为 INET 数据类型。我知道 psycopg2 支持 INET 数据类型,但我很确定当前版本的 py-postgresql 不支持该数据类型(截至 2011 年 5 月 19 日)。这意味着您有三个选择:

  1. py-postgresql 需要添加对 INET 数据类型的支持
  2. ,您可以传入 TEXT 类型的数据,然后在服务器上将其转换为 INET,
  3. 切换到 psycopg2,后者确实支持 INET 数据类型。

http://initd.org/psycopg/docs/extras.html#inet -数据类型

@mrlanrat, it's because the python library is sending your parameters as a TEXT data type but PostgreSQL is expecting an INET data type. Your example there changes the parameters so that PostgreSQL is expecting a TEXT data type, which it then casts in to an INET data type. I know that psycopg2 supports an INET data type but I'm pretty sure the current version of py-postgresql doesn't support the data type (as of 2011-05-19). Which means you have three options:

  1. py-postgresql needs to add support for the INET data type
  2. you get to pass in data of type TEXT and then cast it to INET on the server
  3. switch to psycopg2, which does support the INET data type.

http://initd.org/psycopg/docs/extras.html#inet-data-type

贪了杯 2024-11-15 11:41:03

我一整天都遇到这个问题,但找不到任何解决方案,所以显然我在此处发布后几分钟就自己找到了解决方案。

我需要将 $1 替换为 inet($1::varchar) ,似乎 postgresql 在转换为 inet 值时不喜欢它是字符串,并且您必须将其类型转换为 varchar,然后将该值转换为 inet 变量。

所以,工作路线是:

aID = db.prepare('SELECT id FROM a_records WHERE ip = inet($1::varchar) LIMIT 1')

任何人都可以解释为什么会这样,以及为什么它不会像我一开始尝试的那样工作?

谢谢!

I've been having this problem all day, and I could not find any solution, so obviously I found the solution on my own a few minutes after posting here.

I need to replace $1 with inet($1::varchar), it seems that postgresql does not like it being a string when converting to an inet value, and you must typecast it as a varchar, and then turn the value into an inet variable.

So, the working line is:

aID = db.prepare('SELECT id FROM a_records WHERE ip = inet($1::varchar) LIMIT 1')

Can anyone explain why this is, and why it wont work the way I tried to at first?

Thanks!

不可一世的女人 2024-11-15 11:41:03

您应该显式地将 string 转换为 inet 数据类型。

aID = db.prepare('SELECT id FROM a_records WHERE ip = inet($1) LIMIT 1')

You should explicitly cast string to inet data type.

aID = db.prepare('SELECT id FROM a_records WHERE ip = inet($1) LIMIT 1')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文