【问题标题】:How can I avoid escape chars in inserted binary string with Elixir/Ecto/Postgrex?如何避免使用 Elixir/Ecto/Postgrex 在插入的二进制字符串中出现转义字符?
【发布时间】:2021-05-18 16:08:04
【问题描述】:

我是 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 洞察,我在changeinsert 调用之间添加了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 ($1,$2,$3,$4,$5,$6,$7,$8) 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,以便记录它的查询并最终导致字符串转换/转义 error_data 二进制文件...

【问题讨论】:

    标签: string postgresql base64 elixir ecto


    【解决方案1】:

    它们实际上并不存在,它们只是由您用来打印该值的任何工具显示,因为该工具使用"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
    

    更新

    这是我在精确运行您上面在字符串 (varchar) 字段上显示的代码后运行 psql 查询:

    testdb=# select error_data from tt;
                                      error_data                                  
    -------------------------------------------------------------------------
     {"message":"Invalid token","cause":[],"error":"not_found","status":401}
    (1 row)
    

    【讨论】:

    • 我从数据库查询中看到它(SELECT * FROM error_table)。我在旁边插入了一个普通的未转义内容,因此两者都显示在查询结果中。我测试的那个没问题。我无法在此处附加 /mage,否则我可以显示它。
    • 您需要向我们展示您所看到的内容。我刚刚更新了我的答案,显示了在我创建的新表上精确运行您为新字符串字段获得的代码的结果。所以,有些细节你没有解释/展示。
    猜你喜欢
    • 2016-04-21
    • 2016-09-20
    • 1970-01-01
    • 1970-01-01
    • 2014-04-26
    • 2019-02-25
    • 2011-07-11
    • 1970-01-01
    • 2017-03-22
    相关资源
    最近更新 更多