Thread: plpythonu and bytea
Hey, I'm trying to write some plpython procedures that read binary data from images on the disk and store it in bytea fields. I'm basically trying to write a plpython procedure that accepts a varchar and returns a bytea, with these procedure contents:
data = file(args[0]).read()
return data
(The actual procedure will have more in it, but that's the tricky part). But the returned data is always severely truncated. Is returning a bytea from plpython impossible, or is there some way I should escape the data string? I've tried using the built in encode and decode functions, but they don't seem to help. If worse comes to worse, I can store the base64 encoded version, of course, but I'd rather not do that. Any ideas?
Greg
data = file(args[0]).read()
return data
(The actual procedure will have more in it, but that's the tricky part). But the returned data is always severely truncated. Is returning a bytea from plpython impossible, or is there some way I should escape the data string? I've tried using the built in encode and decode functions, but they don't seem to help. If worse comes to worse, I can store the base64 encoded version, of course, but I'd rather not do that. Any ideas?
Greg
On Sat, Jul 02, 2005 at 04:49:23PM -0400, Greg Steffensen wrote: > > Hey, I'm trying to write some plpython procedures that read binary data from > images on the disk and store it in bytea fields. I'm basically trying to > write a plpython procedure that accepts a varchar and returns a bytea, with > these procedure contents: > > data = file(args[0]).read() > return data > > (The actual procedure will have more in it, but that's the tricky part). But > the returned data is always severely truncated. Is returning a bytea from > plpython impossible, or is there some way I should escape the data string? I think the return value is a cstring that's cast to whatever type the function is declared to return; I'd guess it's being truncated because it contains NUL (\000) values. Example: CREATE FUNCTION foo() RETURNS bytea AS $$ data = '\001\002\000\003\004' return data $$ LANGUAGE plpythonu; SELECT foo(), length(foo()); foo | length ----------+-------- \001\002 | 2 (1 row) The function should work if the data is escaped. I don't know the best Python way to do that, but the following appears to work: CREATE FUNCTION foo() RETURNS bytea AS $$ data = '\001\002\000\003\004' return ''.join(['\\%03o' % ord(x) for x in data]) $$ LANGUAGE plpythonu; SELECT foo(), length(foo()); foo | length ----------------------+-------- \001\002\000\003\004 | 5 (1 row) It seems like there ought to be a better way than the list comprehension shown; maybe you or somebody else with better Python skills can improve on it. -- Michael Fuhr http://www.fuhr.org/~mfuhr/