如何避免使用 Elixir/Ecto/Postgrex 插入二进制字符串中的转义字符?
How can I avoid escape chars in inserted binary string with Elixir/Ecto/Postgrex?
我是 elixir/ecto 的新手,我不明白为什么我的 error_data
字段(在架构中定义为 :binary
)在我的 postgresql 列中插入斜线转义:
params = %{error_data: "eyJtZXNzYWdlIjoiSW52YWxpZCB0b2tlbiIsImNhdXNlIjpbXSwiZXJyb3IiOiJub3RfZm91bmQiLCJzdGF0dXMiOjQwMX0="}
cast(%{}, params, [:error_data])
|> change(%{error_data: Base.decode64!(params.error_data)})
|> Ecto.Repo.insert()
根据@smathy 的见解,我在 change
和 insert
调用之间放置了一个 IO.puts(get_change(changeset, :error_data)
。它显示数据已被解码并且在插入之前没有被斜线转义。但是显示 Ecto 查询的下一行被转义了...检查我的应用程序的输出:
[info] Creating error for 1 on channel 1
{"message":"Invalid token","cause":[],"error":"not_found","status":401}
[debug] QUERY OK db=0.5ms
INSERT INTO "errors" ("code","error","error_message","http_status","id","channel_id","inserted_at","updated_at") VALUES (,,,,,,,) RETURNING "id" ["error-03", "{\"message\":\"Invalid token\",\"cause\":[],\"error\":\"not_found\",\"status\":401}", "Invalid token", 401, 1, 1, ~N[2021-02-16 12:24:58], ~N[2021-02-16 12:24:58]]
然后检查这些数据库查询:第一个是代码插入错误。最后一个来自手动插入的未转义错误:
dev=# SELECT error FROM errors ORDER BY updated_at DESC limit 1;
error
---------------------------------------------------------------------------------------
"{\"message\":\"Invalid token\",\"cause\":[],\"error\":\"not_found\",\"status\":401}"
(1 row)
dev=# SELECT error FROM errors ORDER BY updated_at ASC limit 1;
error
---------------------
{"eita": "deu pau"}
(1 row)
如何避免转义并插入纯解码 ({"message":"Invalid token","cause":[],"error":"not_found","status":401}
) 内容?
如果我可以在插入中使用 ecto 片段,我会告诉数据库解码 base64 字符串......我也没有找到如何做到这一点......有帮助吗?
我想知道是否有任何环境配置影响 ECTO 以记录它的查询并结束字符串 casting/escaping error_data
二进制...
它们实际上并不存在,它们只是由您用来打印该值的任何工具显示,因为该工具使用 "
s 作为字符串分隔符,因此将它们转义为避免歧义。
同样的事情发生在 iex
会话中,如果您实际打印出该值,那么它会按照您的预期出现,因为当您输出字符串时,它不会包含分隔符:
iex(6)> Base.decode64! "eyJtZXNzYWdlIjoiSW52YWxpZCB0b2tlbiIsImNhdXNlIjpbXSwiZXJyb3IiOiJub3RfZm91bmQiLCJzdGF0dXMiOjQwMX0="
"{\"message\":\"Invalid token\",\"cause\":[],\"error\":\"not_found\",\"status\":401}"
iex(7)> IO.puts v
{"message":"Invalid token","cause":[],"error":"not_found","status":401}
:ok
更新
这是我 运行 运行 之后的 psql
查询,正是您在上面显示的字符串 (varchar) 字段中的代码:
testdb=# select error_data from tt;
error_data
-------------------------------------------------------------------------
{"message":"Invalid token","cause":[],"error":"not_found","status":401}
(1 row)
我是 elixir/ecto 的新手,我不明白为什么我的 error_data
字段(在架构中定义为 :binary
)在我的 postgresql 列中插入斜线转义:
params = %{error_data: "eyJtZXNzYWdlIjoiSW52YWxpZCB0b2tlbiIsImNhdXNlIjpbXSwiZXJyb3IiOiJub3RfZm91bmQiLCJzdGF0dXMiOjQwMX0="}
cast(%{}, params, [:error_data])
|> change(%{error_data: Base.decode64!(params.error_data)})
|> Ecto.Repo.insert()
根据@smathy 的见解,我在 change
和 insert
调用之间放置了一个 IO.puts(get_change(changeset, :error_data)
。它显示数据已被解码并且在插入之前没有被斜线转义。但是显示 Ecto 查询的下一行被转义了...检查我的应用程序的输出:
[info] Creating error for 1 on channel 1
{"message":"Invalid token","cause":[],"error":"not_found","status":401}
[debug] QUERY OK db=0.5ms
INSERT INTO "errors" ("code","error","error_message","http_status","id","channel_id","inserted_at","updated_at") VALUES (,,,,,,,) RETURNING "id" ["error-03", "{\"message\":\"Invalid token\",\"cause\":[],\"error\":\"not_found\",\"status\":401}", "Invalid token", 401, 1, 1, ~N[2021-02-16 12:24:58], ~N[2021-02-16 12:24:58]]
然后检查这些数据库查询:第一个是代码插入错误。最后一个来自手动插入的未转义错误:
dev=# SELECT error FROM errors ORDER BY updated_at DESC limit 1;
error
---------------------------------------------------------------------------------------
"{\"message\":\"Invalid token\",\"cause\":[],\"error\":\"not_found\",\"status\":401}"
(1 row)
dev=# SELECT error FROM errors ORDER BY updated_at ASC limit 1;
error
---------------------
{"eita": "deu pau"}
(1 row)
如何避免转义并插入纯解码 ({"message":"Invalid token","cause":[],"error":"not_found","status":401}
) 内容?
如果我可以在插入中使用 ecto 片段,我会告诉数据库解码 base64 字符串......我也没有找到如何做到这一点......有帮助吗?
我想知道是否有任何环境配置影响 ECTO 以记录它的查询并结束字符串 casting/escaping error_data
二进制...
它们实际上并不存在,它们只是由您用来打印该值的任何工具显示,因为该工具使用 "
s 作为字符串分隔符,因此将它们转义为避免歧义。
同样的事情发生在 iex
会话中,如果您实际打印出该值,那么它会按照您的预期出现,因为当您输出字符串时,它不会包含分隔符:
iex(6)> Base.decode64! "eyJtZXNzYWdlIjoiSW52YWxpZCB0b2tlbiIsImNhdXNlIjpbXSwiZXJyb3IiOiJub3RfZm91bmQiLCJzdGF0dXMiOjQwMX0="
"{\"message\":\"Invalid token\",\"cause\":[],\"error\":\"not_found\",\"status\":401}"
iex(7)> IO.puts v
{"message":"Invalid token","cause":[],"error":"not_found","status":401}
:ok
更新
这是我 运行 运行 之后的 psql
查询,正是您在上面显示的字符串 (varchar) 字段中的代码:
testdb=# select error_data from tt;
error_data
-------------------------------------------------------------------------
{"message":"Invalid token","cause":[],"error":"not_found","status":401}
(1 row)