I would like to declare and share some simple, pure python functions between two or more PL/Python functions. I am using Postgres 9.3.
For example, I have:
CREATE OR REPLACE FUNCTION get_mod(modifier varchar)
RETURNS varchar
AS $$
def is_float(val):
try:
if val:
float(val)
return True
else:
return False
except ValueError:
return False
if modifier is None:
return "NOMOD"
if is_float(modifier):
return str(float(modifier)*1)
return modifier
$$ LANGUAGE plpythonu;
I would like to use function is_float
in some other PL/Python function.
I understand I could create it as callable PL/Python function, but I find that much clunkier (to execute SQL-based call to PL/Python) than just making a straight call to a pure Python, custom utility function.
Is it possible to create and expose through PL/Python reusable pure Python functions on Postgres?
And when it comes to reusing code in Python, it all starts and ends with the humble function. Take some lines of code, give them a name, and you've got a function (which can be reused). Take a collection of functions and package them as a file, and you've got a module (which can also be reused).
In Python, any written function can be called by another function. Note that this could be the most elegant way of breaking a problem into chunks of small problems.
To use functions in Python, you write the function name (or the variable that points to the function object) followed by parentheses (to call the function). If that function accepts arguments (as most functions do), then you'll pass the arguments inside the parentheses as you call the function.
In Python, def keyword is used to declare user defined functions. An indented block of statements follows the function name and arguments which contains the body of the function.
What I usually do is pass the functions around using GD. The downside is that since GD is a per session object you need to load it each time you start a new session. The way you can approach this is to have a bootstrap function that you run at the beginning of each session that primes the database for further use. Something like:
create or replace function bootstrap() returns void
as
$$
def is_float(val):
# did some simplifying here,
try:
float(val) # Take notice that booleans will convert to float successfully
return True
except (ValueError, TypeError):
return False
GD['is_float'] = is_float
$$ language plpythonu;
Now you can modify your original function:
CREATE OR REPLACE FUNCTION get_mod(modifier varchar)
RETURNS varchar
AS $$
# Optionally run bootstrap() here
plpy.execute("select bootstrap()")
###
if modifier is None:
return "NOMOD"
if GD['is_float'](modifier):
return str(float(modifier)*1)
return modifier
$$ LANGUAGE plpythonu;
In order for this to work you'd have to run select bootstrap();
at the start of each session, or as part of the first function you are calling as part of the flow... Or indeed as part of your original function.
One option is to create a module and then import it. You can add its location to PYTHONPATH
as described here to ensure the runtime can find it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With