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.

我想知道为什么它会返回这个,因为当你 selectinteger 类型上使用 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 的转换(抱歉)。您有一些选择:

  1. 在您的查询中转换为 ::text(不推荐,因为您每次都会转换每一行)。

    SELECT * FROM my_table WHERE my_uuid::TEXT = 'invalid uid';
    
  2. 不要将其存储为 UUID 类型。如果您不想/不需要 UUID 语义,请将其存储为 varchar。
  3. 检查您的客户输入。 (我的建议)。从概念上讲,这与询问某人的年龄并得到 '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,这对用户来说不是很友好;如果他们只是点击链接而不是输入链接,就像通常发生的那样,那么这个错误是怎么发生的呢?这很有可能是某种攻击,您应该做出相应的反应。