The PL/Python language module automatically imports a Python module
called <literal>plpy</literal>. The functions and constants in
this module are available to you in the Python code as
<literal>plpy.<replaceable>foo</replaceable></literal>.
PL/Python言語モジュールは自動的にplpy
というPythonモジュールをインポートします。
このモジュールの関数と定数は、plpy.
のように作成したPythonコードから使用することができます。
foo
The <literal>plpy</literal> module provides several functions to execute
database commands:
plpy
モジュールはデータベースコマンドを実行するために数個の関数を用意しています。
plpy.execute
(query
[, limit
])
Calling <function>plpy.execute</function> 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.
plpy.execute
を、問い合わせ文字列および省略可能な行数制限引数を付けて呼び出すと、問い合わせが実行され、結果オブジェクトとして問い合わせ結果が返ります。
If <replaceable>limit</replaceable> is specified and is greater than
zero, then <function>plpy.execute</function> retrieves at
most <replaceable>limit</replaceable> rows, much as if the query
included a <literal>LIMIT</literal>
clause. Omitting <replaceable>limit</replaceable> or specifying it as
zero results in no row limit.
limit
が指定され、ゼロより大きい場合、plpy.execute
は、問い合わせにLIMIT
句が含まれているかのように、最大limit
行を取得します。
limit
を省略するか、ゼロとして指定すると、行制限はありません。
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 <literal>my_table</literal>. If
<literal>my_table</literal> has a column
<literal>my_column</literal>, it would be accessed as:
これは、my_table
から5行までを返します。
my_table
にmy_column
列が存在する場合、その列には以下のようにアクセスできます。
foo = rv[i]["my_column"]
The number of rows returned can be obtained using the built-in
<function>len</function> function.
戻った行数はビルトインlen
関数を使用して取得できます。
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 <command>UPDATE</command> command will set this value but
won't return any rows (unless <literal>RETURNING</literal> is used).
コマンドによる処理の行数を返します。
戻った行数と同じとは限らないことに注意してください。
例えば、UPDATE
コマンドではゼロでない値を返しますが、行を戻すことはありません(RETURNING
を使用したときは別です)。
status
()
The <function>SPI_execute()</function> return value.
SPI_execute()
関数の戻り値を返します。
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. 各々、列名のリスト、列の型OIDのリスト、列に関する型独自の型修飾子のリストを返します。
These methods raise an exception when called on a result object from
a command that did not produce a result set, e.g.,
<command>UPDATE</command> without <literal>RETURNING</literal>, or
<command>DROP TABLE</command>. But it is OK to use these methods on
a result set containing zero rows.
RETURNING
を持たないUPDATE
やDROP TABLE
など、結果セットを生成しないコマンドによる結果オブジェクトに対して呼び出された場合、これらのメソッドは例外を発生します。
しかし、ゼロ行の結果セットに対してこれらのメソッドを使用することには問題ありません。
__str__
()
The standard <literal>__str__</literal> method is defined so that it
is possible for example to debug query execution results
using <literal>plpy.debug(rv)</literal>.
標準の__str__
メソッドが定義されていますので、例えば問い合わせの実行結果をplpy.debug(rv)
を使ってデバッグできます。
The result object can be modified. 結果オブジェクトは変更できます。
Note that calling <literal>plpy.execute</literal> 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 <literal>plpy.cursor</literal> rather
than <literal>plpy.execute</literal>.
plpy.execute
を呼び出すことにより、結果セット全体がメモリ内に読み込まれることに注意してください。
結果セットが比較的小さいことが確実な場合だけ、この関数を使用してください。
大規模な結果を取り込む場合の過度のメモリ使用に関する危険を回避したい場合は、plpy.execute
ではなくplpy.cursor
を使用してください。
plpy.prepare
(query
[, argtypes
])
plpy.execute
(plan
[, arguments
[, limit
]])
<indexterm><primary>preparing a query</primary><secondary>in PL/Python</secondary></indexterm>
<function>plpy.prepare</function> 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:
plpy.prepare
は問い合わせの実行計画を準備します。
問い合わせ内にパラメータ参照がある場合、問い合わせ文字列および引数型のリストとともに呼び出されます。
例を示します。
plan = plpy.prepare("SELECT last_name FROM my_users WHERE first_name = $1", ["text"])
<literal>text</literal> is the type of the variable you will be passing
for <literal>$1</literal>. The second argument is optional if you don't
want to pass any parameters to the query.
text
は$1
として渡される変数の型です。
問い合わせにパラメータを渡さない場合、2番目の引数は省略可能です。
After preparing a statement, you use a variant of the
function <function>plpy.execute</function> to run it:
文を準備した後、それを実行するために関数plpy.execute
の亜種を使用します。
rv = plpy.execute(plan, ["name"], 5)
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. 実行計画を(問い合わせ文字列ではなく)最初の引数として渡してください。 問い合わせに代入する値のリストを、2番目の引数として渡してください。 問い合わせにパラメータがない場合、2番目の引数は省略可能です。 3番目の引数は、前に述べた省略可能な行数制限引数です。
Alternatively, you can call the <function>execute</function> method on
the plan object:
代わりに、計画オブジェクトのexecute
メソッドを呼び出すことができます。
rv = plan.execute(["name"], 5)
Query parameters and result row fields are converted between PostgreSQL and Python data types as described in <xref linkend="plpython-data"/>. 問い合わせパラメータおよび結果行のフィールドは44.2で示した通り、PostgreSQLとPythonのデータ型の間で変換されます。
When you prepare a plan using the PL/Python module it is automatically
saved. Read the SPI documentation (<xref linkend="spi"/>) 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 <literal>SD</literal> or <literal>GD</literal> (see
<xref linkend="plpython-sharing"/>). For example:
PL/Pythonモジュールを使用して準備した計画は自動的に保存されます。
これが何を意味するのかについてはSPIの文書(第45章)を参照してください。
これを複数呼び出しにおいて効果的に使用するためには、永続的な格納用辞書であるSD
またはGD
(44.3を参照)のいずれかを使用する必要があります。
例を示します。
CREATE FUNCTION usesavedplan() RETURNS trigger AS $$ if "plan" in SD: plan = SD["plan"] else: plan = plpy.prepare("SELECT 1") SD["plan"] = plan # rest of function $$ LANGUAGE plpython3u;
plpy.cursor
(query
)
plpy.cursor
(plan
[, arguments
])
The <literal>plpy.cursor</literal> function accepts the same arguments
as <literal>plpy.execute</literal> (except for the row limit) and returns
a cursor object, which allows you to process large result sets in smaller
chunks. As with <literal>plpy.execute</literal>, either a query string
or a plan object along with a list of arguments can be used, or
the <function>cursor</function> function can be called as a method of
the plan object.
plpy.cursor
関数はplpy.execute
と同じ引数を受け取り(行数制限引数を除いた)カーソルオブジェクトとして返します。
これにより大規模な結果セットをより小さな塊の中で処理することができます。
plpy.execute
の場合と同様、問い合わせ文字列または引数リスト付きの計画オブジェクトを使用できますし、計画オブジェクトのメソッドとしてcursor
関数を呼ぶことができます。
The cursor object provides a <literal>fetch</literal> method that accepts
an integer parameter and returns a result object. Each time you
call <literal>fetch</literal>, the returned object will contain the next
batch of rows, never larger than the parameter value. Once all rows are
exhausted, <literal>fetch</literal> starts returning an empty result
object. Cursor objects also provide an
<ulink url="https://docs.python.org/library/stdtypes.html#iterator-types">iterator
interface</ulink>, 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.
カーソルオブジェクトは、整数パラメータを受付け、結果オブジェクトを返すfetch
メソッドを提供します。
fetch
を呼び出す度に、返されるオブジェクトには次の一群の行が含まれます。
この行数はパラメータ値より多くなることはありません。
全ての行が出し尽くされると、fetch
は空の結果オブジェクトを返すようになります。
カーソルオブジェクトはまた、すべての行を出し尽くすまで一度に1行を生成するイテレータインタフェースを提供します。
この方法で取り出されたデータは結果オブジェクトとしては返されず、1つの辞書が単一の結果行に対応する辞書群として返されます。
An example of two ways of processing data from a large table is: 大きなテーブルのデータを処理する、2つの方法の例を示します。
CREATE FUNCTION count_odd_iterator() RETURNS integer AS $$
odd = 0
for row in plpy.cursor("select num from largetable"):
if row['num'] % 2:
odd += 1
return odd
$$ LANGUAGE plpython3u;
CREATE FUNCTION count_odd_fetch(batch_size integer) RETURNS integer AS $$
odd = 0
cursor = plpy.cursor("select num from largetable")
while True:
rows = cursor.fetch(batch_size)
if not rows:
break
for row in rows:
if row['num'] % 2:
odd += 1
return odd
$$ LANGUAGE plpython3u;
CREATE FUNCTION count_odd_prepared() RETURNS integer AS $$
odd = 0
plan = plpy.prepare("select num from largetable where num % $1 <> 0", ["integer"])
rows = list(plpy.cursor(plan, [2])) # or: = list(plan.cursor([2]))
rows = list(plpy.cursor(plan, [2])) # または = list(plan.cursor([2]))
return len(rows)
$$ LANGUAGE plpython3u;
Cursors are automatically disposed of. But if you want to explicitly
release all resources held by a cursor, use the <literal>close</literal>
method. Once closed, a cursor cannot be fetched from anymore.
カーソルは自動的に処分されます。
しかし、カーソルが保有していた資源を明示的に解放したい場合は、close
メソッドを使用してください。
閉じた後、カーソルからこれ以上取り込むことはできません。
Do not confuse objects created by <literal>plpy.cursor</literal> with
DB-API cursors as defined by
the <ulink url="https://www.python.org/dev/peps/pep-0249/">Python
Database API specification</ulink>. They don't have anything in common
except for the name.
plpy.cursor
によって作成されたオブジェクトと、PythonデータベースAPI仕様において定義されたDB-APIカーソルとを混同しないでください。
名称以外の共通点はありません。
Functions accessing the database might encounter errors, which
will cause them to abort and raise an exception. Both
<function>plpy.execute</function> and
<function>plpy.prepare</function> can raise an instance of a subclass of
<literal>plpy.SPIError</literal>, which by default will terminate
the function. This error can be handled just like any other
Python exception, by using the <literal>try/except</literal>
construct. For example:
データベースにアクセスする関数はエラーに遭遇し、エラーが関数をアボートして例外を発生させる原因となります。
plpy.execute
およびplpy.prepare
は、デフォルトでは関数を終了させるplpy.SPIError
のサブクラスのインスタンスを発生させることができます。
このエラーは、try/except
構文を使用して、Pythonの他の例外と同様に処理できます。
例を示します。
CREATE FUNCTION try_adding_joe() RETURNS text AS $$ try: plpy.execute("INSERT INTO users(username) VALUES ('joe')") except plpy.SPIError: return "something went wrong" "うまくいかなかった" を返す else: return "Joe added" "Joeが追加された" を返す $$ LANGUAGE plpython3u;
The actual class of the exception being raised corresponds to the
specific condition that caused the error. Refer
to <xref linkend="errcodes-table"/> for a list of possible
conditions. The module
<literal>plpy.spiexceptions</literal> defines an exception class
for each <productname>PostgreSQL</productname> condition, deriving
their names from the condition name. For
instance, <literal>division_by_zero</literal>
becomes <literal>DivisionByZero</literal>, <literal>unique_violation</literal>
becomes <literal>UniqueViolation</literal>, <literal>fdw_error</literal>
becomes <literal>FdwError</literal>, and so on. Each of these
exception classes inherits from <literal>SPIError</literal>. This
separation makes it easier to handle specific errors, for
instance:
発生される例外の実クラスはエラーを引き起こした特定の条件と対応します。
表 A.1にあり得る条件のリストがありますので参照してください。
plpy.spiexceptions
モジュールはPostgreSQLの条件それぞれに対して、その条件名に因んだ名前の例外クラスを定義しています。
例えばdivision_by_zero
はDivisionByZero
、unique_violation
はUniqueViolation
に、fdw_error
はFdwError
などのようになります。
これらの例外クラスはそれぞれSPIError
を継承したものです。
このように分離することで特定のエラーをより簡単に扱うことができるようになります。
以下に例を示します。
CREATE FUNCTION insert_fraction(numerator int, denominator int) RETURNS text AS $$ from plpy import spiexceptions try: plan = plpy.prepare("INSERT INTO fractions (frac) VALUES ($1 / $2)", ["int", "int"]) plpy.execute(plan, [numerator, denominator]) except spiexceptions.DivisionByZero: return "denominator cannot equal zero" except spiexceptions.UniqueViolation: return "already have that fraction" except plpy.SPIError as e: return "other error, SQLSTATE %s" % e.sqlstate else: return "fraction inserted" $$ LANGUAGE plpython3u;
Note that because all exceptions from
the <literal>plpy.spiexceptions</literal> module inherit
from <literal>SPIError</literal>, an <literal>except</literal>
clause handling it will catch any database access error.
plpy.spiexceptions
モジュールからの全ての例外はSPIError
を継承するため、例外を処理するexcept
句は全てのデータベースアクセスエラーを捕捉することに注意してください。
As an alternative way of handling different error conditions, you
can catch the <literal>SPIError</literal> exception and determine
the specific error condition inside the <literal>except</literal>
block by looking at the <literal>sqlstate</literal> attribute of
the exception object. This attribute is a string value containing
the <quote>SQLSTATE</quote> error code. This approach provides
approximately the same functionality
異なったエラー条件を処理する代りの方法として、SPIError
例外を捕捉して、例外オブジェクトのsqlstate
属性を調べることにより、except
ブロック内部の明細なエラー条件を決定できます。
この属性は「SQLSTATE」エラーコードを含む文字列値です。
この方法は、ほぼ同じ機能を提供します。