PostgreSQL UUID 日期类型
PostgreSQL UUID date type
我正在构建一个带有 PostgreSQL 数据库的平台(第一次),但我已经使用 Oracle 和 MySQL 数据库几年了。
我的问题是关于 Postgres 中的 UUID 数据类型。
我正在使用 UUIDv4 uuid 来标识多个表中的记录,因此对 /users/2df2ab0c-bf4c-4eb5-9119-c37aa6c6b172 的请求将响应具有该 UUID 的用户。我还有一个用于索引的自动递增 ID 字段。
我的查询只是一个 select
,在 UUID
上有一个 where
子句。但是当用户输入像这样的无效 UUID 2df2ab0c-bf4c-4eb5-9119-c37aa6c6b17
(没有最后一个 2
)时,数据库会响应此错误:Invalid input syntax for UUID
.
我想知道为什么它会返回这个,因为当你 select
在 integer
类型上使用 string
类型时它确实有效。
现在我需要在每条包含 UUID
类型参数的路由上设置一个 middleware/check,否则服务器会崩溃。
顺便说一句,我正在使用 Flask 0.12 (Python) 和 PostgreSQL 9.6
UUID as defined by RFC 4122, ISO/IEC 9834-8:2005... is a 128-bit quantity ... written as a sequence of lower-case hexadecimal digits... for a total of 32 digits representing the 128 bits. (Postgresql Docs)
没有从 31 位十六进制数字文本到 128 位 UUID 的转换(抱歉)。您有一些选择:
在您的查询中转换为 ::text(不推荐,因为您每次都会转换每一行)。
SELECT * FROM my_table WHERE my_uuid::TEXT = 'invalid uid';
- 不要将其存储为 UUID 类型。如果您不想/不需要 UUID 语义,请将其存储为 varchar。
- 检查您的客户输入。 (我的建议)。从概念上讲,这与询问某人的年龄并得到 'ABC' 作为响应没有什么不同。
Postgres 允许 upper/lower 大小写,并且可以灵活使用连字符,所以 pre-check 只是去掉连字符,小写,计数 [0-9[a-f]
& if == 32,你有一个可用的 UUID。否则,与其告诉用户 "not found",不如告诉他们 "not a UUID",这可能更 user-friendly.
数据库抛出错误,因为您试图在 UUID 类型的列中匹配 不包含有效 UUID 的查询。这不会发生在整数或字符串查询中,因为省略那些 does 的最后一个字符会导致有效的整数或字符串,而不是您可能想要的。
您可以通过验证您的输入(出于其他原因您应该这样做)来防止将无效的 UUID 传递到数据库,或者以某种方式捕获此错误。无论哪种方式,您都需要向用户返回一条人类可读的错误消息。
还要考虑用户是否应该首先输入带有 UUID 的 URL,这对用户来说不是很友好;如果他们只是点击链接而不是输入链接,就像通常发生的那样,那么这个错误是怎么发生的呢?这很有可能是某种攻击,您应该做出相应的反应。
我正在构建一个带有 PostgreSQL 数据库的平台(第一次),但我已经使用 Oracle 和 MySQL 数据库几年了。
我的问题是关于 Postgres 中的 UUID 数据类型。 我正在使用 UUIDv4 uuid 来标识多个表中的记录,因此对 /users/2df2ab0c-bf4c-4eb5-9119-c37aa6c6b172 的请求将响应具有该 UUID 的用户。我还有一个用于索引的自动递增 ID 字段。
我的查询只是一个 select
,在 UUID
上有一个 where
子句。但是当用户输入像这样的无效 UUID 2df2ab0c-bf4c-4eb5-9119-c37aa6c6b17
(没有最后一个 2
)时,数据库会响应此错误:Invalid input syntax for UUID
.
我想知道为什么它会返回这个,因为当你 select
在 integer
类型上使用 string
类型时它确实有效。
现在我需要在每条包含 UUID
类型参数的路由上设置一个 middleware/check,否则服务器会崩溃。
顺便说一句,我正在使用 Flask 0.12 (Python) 和 PostgreSQL 9.6
UUID as defined by RFC 4122, ISO/IEC 9834-8:2005... is a 128-bit quantity ... written as a sequence of lower-case hexadecimal digits... for a total of 32 digits representing the 128 bits. (Postgresql Docs)
没有从 31 位十六进制数字文本到 128 位 UUID 的转换(抱歉)。您有一些选择:
在您的查询中转换为 ::text(不推荐,因为您每次都会转换每一行)。
SELECT * FROM my_table WHERE my_uuid::TEXT = 'invalid uid';
- 不要将其存储为 UUID 类型。如果您不想/不需要 UUID 语义,请将其存储为 varchar。
- 检查您的客户输入。 (我的建议)。从概念上讲,这与询问某人的年龄并得到 'ABC' 作为响应没有什么不同。
Postgres 允许 upper/lower 大小写,并且可以灵活使用连字符,所以 pre-check 只是去掉连字符,小写,计数 [0-9[a-f]
& if == 32,你有一个可用的 UUID。否则,与其告诉用户 "not found",不如告诉他们 "not a UUID",这可能更 user-friendly.
数据库抛出错误,因为您试图在 UUID 类型的列中匹配 不包含有效 UUID 的查询。这不会发生在整数或字符串查询中,因为省略那些 does 的最后一个字符会导致有效的整数或字符串,而不是您可能想要的。
您可以通过验证您的输入(出于其他原因您应该这样做)来防止将无效的 UUID 传递到数据库,或者以某种方式捕获此错误。无论哪种方式,您都需要向用户返回一条人类可读的错误消息。
还要考虑用户是否应该首先输入带有 UUID 的 URL,这对用户来说不是很友好;如果他们只是点击链接而不是输入链接,就像通常发生的那样,那么这个错误是怎么发生的呢?这很有可能是某种攻击,您应该做出相应的反应。