46.6. Database Access
The PL/Python language module automatically imports a Python module called plpy
. The functions and constants in this module are available to you in the Python code as plpy.
foo
.
46.6.1. Database Access Functions
The plpy
module provides several functions to execute database commands:
plpy.execute(
query
[,
max-rows
])
Calling plpy.execute
with a query string and an optional row limit argument causes that query to be run and the result to be returned in a result object.
The result object emulates a list or dictionary object. The result object can be accessed by row number and column name. For example:
returns up to 5 rows from my_table
. If my_table
has a column my_column
, it would be accessed as:
The number of rows returned can be obtained using the built-in len
function.
The result object has these additional methods:
nrows()
Returns the number of rows processed by the command. Note that this is not necessarily the same as the number of rows returned. For example, an UPDATE
command will set this value but won't return any rows (unless RETURNING
is used).
status()
The SPI_execute()
return value.
colnames()
coltypes()
coltypmods()
Return a list of column names, list of column type OIDs, and list of type-specific type modifiers for the columns, respectively.
These methods raise an exception when called on a result object from a command that did not produce a result set, e.g., UPDATE
without RETURNING
, or DROP TABLE
. But it is OK to use these methods on a result set containing zero rows.
__str__()
The standard __str__
method is defined so that it is possible for example to debug query execution results using plpy.debug(rv)
.
The result object can be modified.
Note that calling plpy.execute
will cause the entire result set to be read into memory. Only use that function when you are sure that the result set will be relatively small. If you don't want to risk excessive memory usage when fetching large results, use plpy.cursor
rather than plpy.execute
.
plpy.prepare(
query
[,
argtypes
])
plpy.execute(
plan
[,
arguments
[,
max-rows
]])
plpy.prepare
prepares the execution plan for a query. It is called with a query string and a list of parameter types, if you have parameter references in the query. For example:
text
is the type of the variable you will be passing for $1
. The second argument is optional if you don't want to pass any parameters to the query.
After preparing a statement, you use a variant of the function plpy.execute
to run it:
Pass the plan as the first argument (instead of the query string), and a list of values to substitute into the query as the second argument. The second argument is optional if the query does not expect any parameters. The third argument is the optional row limit as before.
Alternatively, you can call the execute
method on the plan object:
plpy.cursor(
query
)
plpy.cursor(
plan
[,
arguments
])
The plpy.cursor
function accepts the same arguments as plpy.execute
(except for the row limit) and returns a cursor object, which allows you to process large result sets in smaller chunks. As with plpy.execute
, either a query string or a plan object along with a list of arguments can be used, or the cursor
function can be called as a method of the plan object.
An example of two ways of processing data from a large table is:
Cursors are automatically disposed of. But if you want to explicitly release all resources held by a cursor, use the close
method. Once closed, a cursor cannot be fetched from anymore.
Tip
46.6.2. Trapping Errors
Functions accessing the database might encounter errors, which will cause them to abort and raise an exception. Both plpy.execute
and plpy.prepare
can raise an instance of a subclass of plpy.SPIError
, which by default will terminate the function. This error can be handled just like any other Python exception, by using the try/except
construct. For example:
Note that because all exceptions from the plpy.spiexceptions
module inherit from SPIError
, an except
clause handling it will catch any database access error.
As an alternative way of handling different error conditions, you can catch the SPIError
exception and determine the specific error condition inside the except
block by looking at the sqlstate
attribute of the exception object. This attribute is a string value containing the “SQLSTATE” error code. This approach provides approximately the same functionality
Was this helpful?