From 206bec11bd9214873e3703898958789324480b1f Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 26 Mar 2012 21:15:16 +0300 Subject: [PATCH] Improve PL/Python database access function documentation Organize the function descriptions as a list instead of running text, for easier access. --- doc/src/sgml/plpython.sgml | 263 ++++++++++++++++++++++--------------- 1 file changed, 159 insertions(+), 104 deletions(-) diff --git a/doc/src/sgml/plpython.sgml b/doc/src/sgml/plpython.sgml index 237c881a5c..75a939406c 100644 --- a/doc/src/sgml/plpython.sgml +++ b/doc/src/sgml/plpython.sgml @@ -877,134 +877,169 @@ $$ LANGUAGE plpythonu; Database Access Functions - The plpy module provides two - functions called execute and - prepare. Calling - plpy.execute with a query string and an - optional 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. It has these additional methods: - nrows which returns the number of rows - returned by the query, status which is the - SPI_execute() return value, - colnames which is the list of column names, - coltypes which is the list of column type OIDs, - and coltypmods which is the list of type-specific type - modifiers for the columns. The result object can be modified. + The plpy module provides several functions to execute + database commands: - - 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.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. + - - For example: + + The result object emulates a list or dictionary object. The result + object can be accessed by row number and column name. For example: rv = plpy.execute("SELECT * FROM my_table", 5) - returns up to 5 rows from my_table. If - my_table has a column - my_column, it would be accessed as: + returns up to 5 rows from my_table. If + my_table has a column + my_column, it would be accessed as: foo = rv[i]["my_column"] - + - - preparing a queryin PL/Python - The second function, 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: + + The result object has these additional methods: + + + nrows() + + + Returns the number of rows returned or processed by the query. + + + + + + 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. + + + + + + + + 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]]) + + + preparing a queryin PL/Python + 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: -plan = plpy.prepare("SELECT last_name FROM my_users WHERE first_name = $1", [ "text" ]) +plan = plpy.prepare("SELECT last_name FROM my_users WHERE first_name = $1", ["text"]) - text is the type of the variable you will be - passing for $1. After preparing a statement, you - use the function plpy.execute to run it: + 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: -rv = plpy.execute(plan, [ "name" ], 5) +rv = plpy.execute(plan, ["name"], 5) - The third argument is the limit and is optional. - + 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. + - - Query parameters and result row fields are converted between - PostgreSQL and Python data types as described - in . The exception is that composite - types are currently not supported: They will be rejected as query - parameters and are converted to strings when appearing in a query - result. As a workaround for the latter problem, the query can - sometimes be rewritten so that the composite type result appears as - a result row rather than as a field of the result row. - Alternatively, the resulting string could be parsed apart by hand, - but this approach is not recommended because it is not - future-proof. - + + Query parameters and result row fields are converted between PostgreSQL + and Python data types as described in . + The exception is that composite types are currently not supported: They + will be rejected as query parameters and are converted to strings when + appearing in a query result. As a workaround for the latter problem, the + query can sometimes be rewritten so that the composite type result + appears as a result row rather than as a field of the result row. + Alternatively, the resulting string could be parsed apart by hand, but + this approach is not recommended because it is not future-proof. + - - When you prepare a plan using the PL/Python module it is - automatically saved. Read the SPI documentation () for a description of what this means. - In order to make effective use of this across function calls - one needs to use one of the persistent storage dictionaries - SD or GD (see - ). For example: + + When you prepare a plan using the PL/Python module it is automatically + saved. Read the SPI documentation () for a + description of what this means. In order to make effective use of this + across function calls one needs to use one of the persistent storage + dictionaries SD or GD (see + ). For example: CREATE FUNCTION usesavedplan() RETURNS trigger AS $$ plan = SD.setdefault("plan", plpy.prepare("SELECT 1")) # rest of function $$ LANGUAGE plpythonu; - + + + - + + 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. + - - Accessing Data with Cursors + + The cursor object provides a fetch method that accepts + an integer parameter and returns a result object. Each time you + call fetch, the returned object will contain the next + batch of rows, never larger than the parameter value. Once all rows are + exhausted, fetch starts returning an empty result + object. Cursor objects also provide an + iterator + interface, yielding one row at a time until all rows are + exhausted. Data fetched that way is not returned as result objects, but + rather as dictionaries, each dictionary corresponding to a single result + row. + - - The plpy.cursor function accepts the same arguments - as plpy.execute (except for 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. The - cursor object provides a fetch method that accepts an - integer parameter and returns a result object. Each time you - call fetch, the returned object will contain the next - batch of rows, never larger than the parameter value. Once all rows are - exhausted, fetch starts returning an empty result - object. Cursor objects also provide an - iterator - interface, yielding one row at a time until all rows are exhausted. - Data fetched that way is not returned as result objects, but rather as - dictionaries, each dictionary corresponding to a single result row. - - - - 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. - - - - - Do not confuse objects created by plpy.cursor with - DB-API cursors as defined by - the Python Database - API specification. They don't have anything in common except for - the name. - - - - - An example of two ways of processing data from a large table is: + + An example of two ways of processing data from a large table is: CREATE FUNCTION count_odd_iterator() RETURNS integer AS $$ odd = 0 @@ -1035,7 +1070,27 @@ rows = list(plpy.cursor(plan, [2])) return len(rows) $$ LANGUAGE plpythonu; - + + + + 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. + + + + + Do not confuse objects created by plpy.cursor with + DB-API cursors as defined by + the Python + Database API specification. They don't have anything in common + except for the name. + + + + + +