Postgresql SMICK中的Macaddr/Inet型postgres
我的应用程序使用slick(v2.0.0)管理postgresql(9.1)数据库 我的一个表包含网络设备,因此包含mac和ip地址。我使用了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
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
- 插入前需要浇铸此串珠,但可以将其视为字符串
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);