Postgresql SMICK中的Macaddr/Inet型postgres

Postgresql SMICK中的Macaddr/Inet型postgres,postgresql,jdbc,slick,Postgresql,Jdbc,Slick,我的应用程序使用slick(v2.0.0)管理postgresql(9.1)数据库 我的一个表包含网络设备,因此包含mac和ip地址。我使用了postgres类型macaddr和inet,因为它们似乎是完成任务的完美工具。现在我想用slick搭配床上用品,但很难定义我的桌子。当我为我的表自动生成代码时,我注意到使用了String,而不是那些类型,但我并不介意 这对于从数据库读取很好,但是当我尝试更新或插入一行时,它会导致 org.postgresql.util.PSQLException: ER

我的应用程序使用slick(v2.0.0)管理postgresql(9.1)数据库

我的一个表包含网络设备,因此包含mac和ip地址。我使用了postgres类型
macaddr
inet
,因为它们似乎是完成任务的完美工具。现在我想用slick搭配床上用品,但很难定义我的桌子。当我为我的表自动生成代码时,我注意到使用了
String
,而不是那些类型,但我并不介意

这对于从数据库读取很好,但是当我尝试更新或插入一行时,它会导致

org.postgresql.util.PSQLException: ERROR: 
column "mac" is of type macaddr but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
这似乎很合乎逻辑

现在的问题是,我如何才能告诉斯里克:

  • 此COLLMN实际上属于
    macaddr
    /
    inet

  • 插入前需要浇铸此串珠,但可以将其视为字符串
?

更新:

正如Craig所描述的,我已经在中的
macaddr\u和
中的
inet\u周围使用包装函数创建了隐式强制转换

\dC macaddr
                 List of casts
 Source type | Target type |    Function    | Implicit?
-------------+-------------+----------------+-----------
 text        | macaddr     | macaddr_intext | yes

\dC inet
                        List of casts
 Source type |    Target type    |      Function      |   Implicit?
-------------+-------------------+--------------------+---------------
 cidr        | inet              | (binary coercible) | yes
 inet        | character         | text               | in assignment
 inet        | character varying | text               | in assignment
 inet        | cidr              | cidr               | in assignment
 inet        | text              | text               | in assignment
 text        | inet              | inet_intext        | yes

\df+ macaddr_intext
                                                                  List of functions
 Schema |      Name      | Result data type | Argument data types |  Type  | Volatility |  Owner   | Language |           Source code           | Description
--------+----------------+------------------+---------------------+--------+------------+----------+----------+---------------------------------+-------------
 public | macaddr_intext | macaddr          | text                | normal | immutable  | postgres | sql      |                                 |
                                                                                                              : select macaddr_in($1::cstring);
                                                                                                              :

\df+ inet_intext
                                                               List of functions
 Schema |    Name     | Result data type | Argument data types |  Type  | Volatility |  Owner   | Language |         Source code          | Description
--------+-------------+------------------+---------------------+--------+------------+----------+----------+------------------------------+-------------
 public | inet_intext | inet             | text                | normal | immutable  | postgres | sql      |                              |
                                                                                                           : select inet_in($1::cstring);
                                                                                                           :
Errormessage仍然与上面显示的完全相同

要复制的命令:

psql
中:

更新2:

我将其缩小为权限错误,因为如果我以用户身份运行
postgres

mydb=# create table test(i inet, m macaddr)
CREATE TABLE
mydb=# insert into test values ('1.1.1.1'::text, '00:00:00:00:00:00'::text);
INSERT 0 1
但如果我尝试以实际尝试插入的用户的身份运行它

mydb=> insert into test values ('1.1.1.1'::text, '00:00:00:00:00:00'::text);
ERROR: permission denied for relation test
设置我运行的数据库时:

template1=# GRANT ALL PRIVILEGES ON DATABASE mydb to myuser;
更新3:


Update2原来是唯一的问题,因为创建的表是由
postgres
拥有的,而不是
myuser

这是许多人使用
json
XML
时遇到的问题的一个变体,归结为PostgreSQL对数据类型之间的强制转换过于严格

请参阅哪个讨论了与
json
类似的问题。使用转换函数创建强制转换的相同方法在这里也适用

您的cast函数是
中的
macaddr\u和
中的
inet\u。由于一些恼人的类型问题,您需要编写包含
text
参数的包装器SQL函数。请参见上面的链接

另见


更新后,我测试了您的功能,发现它们可以正常工作:

postgres=# CREATE TABLE inetmac (i inet, m macaddr);
CREATE TABLE
postgres=# PREPARE insinet(text) AS INSERT INTO inetmac(i) VALUES ($1);
PREPARE
postgres=# EXECUTE insinet('10.1.1.1');
INSERT 0 1
postgres=# 
。。。但是,令人惊讶的是,Pg没有隐式地从
varchar
转换到
text
,以便使用
text
转换:

postgres=# PREPARE insinet(varchar) AS INSERT INTO inetmac(i) VALUES ($1);
ERROR:  column "i" is of type inet but expression is of type character varying
LINE 1: ...PARE insinet(varchar) AS INSERT INTO inetmac(i) VALUES ($1);
                                                                   ^
HINT:  You will need to rewrite or cast the expression.
如果您使用的是
varchar
input,则需要另一组使用
varchar
而不是
text
input的强制转换

请注意,如果您只是:

INSERT INTO inetmac(i) VALUES ('10.1.1.1');
直接,因为这里的
'10.1.1.1
是伪类型
未知
,并且被解释为
inet
,因为这是输入所需要的。这有点像是一种可以隐式转换为任何输入函数的类型。相比之下,
text
varchar
是Pg必须参考强制转换规则的具体类型,因此如果不创建强制转换,这将不起作用:

INSERT INTO inetmac(i) VALUES ('10.1.1.1'::text);
我要在黑客名单上对此大惊小怪,人们从客户端界面使用PostgreSQL的扩展类型是多么困难,这让人感到痛苦。当然,客户机接口应该公开一种告诉JDBC驱动程序基类型是什么的方法,但是如果大多数事情都能处理诸如索引和复合键之类的极端基础,那么我们就幸运了,更不用说类型处理的细节了。Pg真的需要对此少一点疯狂,或者提供一种方法来指定参数绑定中的
'unknown'
伪类型

引起骚动:


我已经创建了两个包装函数
macaddr\u intext(text)
inet\u intext(text)
,就像您在链接文章中描述的那样,以及使用这些函数的隐式强制转换。但当我尝试插入
macaddr
时,仍然会出现与
text
@mgttlinger正常工作时完全相同的错误;使用精确的函数定义和命令运行编辑问题,新错误(如果更改)?向问题添加函数和强制转换定义。函数的所有者与试图插入的用户不同,这有关系吗?@mgttlinger使用
CREATE
命令会很好,一方面,它会帮助其他人以后找到它。另一方面,它可以帮助我真实地再现你正在做的事情,以了解可能出现的问题。不,只要角色具有执行权限,所有者就不重要。还添加了这些权限。我已授予用户对数据库的所有权限。
INSERT INTO inetmac(i) VALUES ('10.1.1.1'::text);