Reputation: 391
I have built an API on top of Postgres that is routed through a PLPGSQL function that always returns JSONB. eg:-
SELECT api('{"method", "foo"}'::JSONB)
Returns:-
{
"response_code" : 200,
"data" : "...."
}
I want to use this gateway to render vector tiles which are in PBF format. I have a function create_vector_tile(x,y,z) which returns BYTEA and this works perfectly if I connect a python script to it directly:-
query = DATABASE_CONNECTION.execute(create_vector_tile(%,%,%), [x,y,z])
ret = query.fetchone()[0]
self.send_response(200)
self.send_header("Access-Control-Allow-Origin", "*")
self.send_header("Content-type", "application/vnd.mapbox-vector-tile")
self.end_headers()
self.wfile.write(ret)
How do I decode this bytea if I return it via my API eg:-
RETURN json_build_object('response_code', 200, 'data', create_vector_tile(x,y,z))
Postgres automatically encodes the bytea as a string in the JSON object but I don't know how to decode this in python to get the same result as the direct call. I need to go via my API as it does authentication and logging.
Upvotes: 0
Views: 817
Reputation: 55640
Postgresql's BYTEA
is a hex string preceded by \x
. Assuming it arrives with the leading backslash properly escaped it can be converted to bytes using bytes.fromhex:
>>> bytea = '\\x1aa7360a0764656661756c7412820412e10300000101020203030404050506060707080809090a030b0a0c0b0d0c0e0d0f'
>>> bs = bytes.fromhex(bytea[2:])
>>> bs
b'\x1a\xa76\n\x07default\x12\x82\x04\x12\xe1\x03\x00\x00\x01\x01\x02\x02\x03\x03\x04\x04\x05\x05\x06\x06\x07\x07\x08\x08\t\t\n\x03\x0b\n\x0c\x0b\r\x0c\x0e\r\x0f'
If the backslash is not escaped, this will work:
>>> bytea = '\x1aa7360a0764656661756c7412820412e10300000101020203030404050506060707080809090a030b0a0c0b0d0c0e0d0f'
>>> escaped = bytea.encode('unicode-escape').decode('ascii')
>>> bytes.fromhex(escaped[2:])
b'\x1a\xa76\n\x07default\x12\x82\x04\x12\xe1\x03\x00\x00\x01\x01\x02\x02\x03\x03\x04\x04\x05\x05\x06\x06\x07\x07\x08\x08\t\t\n\x03\x0b\n\x0c\x0b\r\x0c\x0e\r\x0f'
Upvotes: 1