简单的例子:
Zlib::Inflate.inflate(PG::Connection.unescape_bytea(PG::Connection.escape_bytea(Zlib::Deflate.deflate('["128,491,128,487"]'))))
Zlib::DataError: incorrect data check
这不是zlib的问题,因为以下成功:
Zlib::Inflate.inflate(Zlib::Deflate.deflate('["128,491,128,487"]'))
=> "[\"128,491,128,487\"]"
解析失败/成功取决于提供的字符串:
Zlib::Inflate.inflate(PG::Connection.unescape_bytea(PG::Connection.escape_bytea(Zlib::Deflate.deflate('["128,491,128,487", "128,491,128,490", "38,465,40,463"]'))))
=> "[\"128,491,128,487\", \"128,491,128,490\", \"38,465,40,463\"]"
我做错了什么或是在ruby破坏的postgres bytea字段中逃脱了吗?我可以做什么替代?
试过:Ruby 2.2.3p173,gem pg-0.18.4; Ruby 2.4.1p111,gem pg-0.21.0
答案 0 :(得分:0)
来自https://bitbucket.org/ged/ruby-pg/issues/262/postgres-bytearray-escaping的答案:
(un)escape_bytea的描述具有误导性。它并不完全相反。
PG :: Connection.escape_bytea使用旧的和不推荐使用的转义机制,必须进行双重转义 - 首先作为BYTEA,辅助作为字符串文字(每次添加'字符串前后)以插入SQL字符串。出于方便和性能原因,这是一步完成的。
相反,PG :: Connection.unescape_bytea只进行BYTEA转义,因为它用于解码查询检索的列数据。此数据不会作为字符串文字进行转义。 您现在有两个选项可以完成上述工作:
enco = PG::TextEncoder::Bytea.new
deco = PG::TextDecoder::Bytea.new
Zlib::Inflate.inflate(deco.decode(enco.encode(Zlib::Deflate.deflate('["128,491,128,487"]'))))
这使用了pg gem的类型编码器而不是libpq。编码器使用较新的BYTEA转义机制,比libpq的功能快一点。这仍然与服务器连接无关。 conn = PG.connect
Zlib::Inflate.inflate(conn.unescape_bytea(conn.escape_bytea(Zlib::Deflate.deflate('["128,491,128,487"]'))))
这使用了libpq的连接绑定转义函数。它们还使用较新的转义机制,因此不会发生双重转义。