Requirements

This version of pg-python is known to work with the following versions of PostgreSQL:

  • PostgreSQL 8.3
  • PostgreSQL 8.4
  • PostgreSQL 8.5 (Alias to 9.0)
  • PostgreSQL 9.0

And the following versions of Python:

  • Python 3.1

Python’s C-APIs are fairly stable, so newer versions of Python are expected to normally work. However, PostgreSQL’s C-APIs and header files can be adjusted from minor release to minor release. If the target version of PostgreSQL is not listed above, it should not be expected to work.

Administration

The administration of procedural language extensions can be tricky in some situations. If you have any questions, be sure to contact the mailing list:

mailto:python-general@pgfoundry.org

Note

This chapter occasionally refers $PREFIX; this is referring to the location in which PostgreSQL is installed. When referenced, it is assumed that the installation did not modify the directory layout. In the event that the distribution or packager did modify the layout, it is important to reference the appropriate documentation in order to properly identify the corresponding locations.

Compilation

Currently, the only supported compilation method uses PostgreSQL’s PGXS makefile system. For compilation, the Python and PostgreSQL header files are necessary, so for some platforms, it is important to install the Python and PostgreSQL developer packages.

PGXS Build

The first step for PGXS compilation is running the configure script. By default, the configure script identifies the PostgreSQL installation and the Python installation to use by executing the python3 command and pg_config command. Whichever python3 and pg_config executable comes first in the system’s path will be the target installation chosen by configure:

./configure

Once configured, the makefile includes have been built, and the GNUmakefile‘s functionality will be ready for use:

# Or "gmake" on some systems.
make

And finally, to install the built module:

# Prefix with "sudo", if need be.
make install

There is only one file that needs to be installed, normally named python.so. make install will place it in the $PREFIX/lib/postgresql directory.

Database Installation

Installation into a database is the last necessary step before a Python FUNCTION can be created. This is normally done by executing the following commands:

BEGIN;
CREATE SCHEMA __python__;
SET search_path TO __python__;
CREATE FUNCTION handler() RETURNS LANGUAGE_HANDLER
 LANGUAGE C AS 'python', 'pl_handler';
CREATE FUNCTION validator(oid) RETURNS VOID
 LANGUAGE C AS 'python', 'pl_validator';
COMMIT;

-- For 9.0 and greater.
BEGIN;
SET search_path TO __python__;
CREATE FUNCTION inline(INTERNAL) RETURNS VOID
 LANGUAGE C AS 'python', 'pl_inline';
CREATE LANGUAGE python
 HANDLER handler INLINE inline VALIDATOR validator;
COMMIT;

-- For versions before 9.0.
BEGIN;
SET search_path TO __python__;
CREATE LANGUAGE python
 HANDLER handler VALIDATOR validator;
COMMIT;

The distinct schema is used hold the functions and for future expansion.

Tip

If a language is installed into template1, all subsequently created databases will have the language installed automatically.

The above commands will only work if the extension module is installed into PostgreSQL’s library directory. Normally, $PREFIX/lib/postgresql. In cases where the extension does not exist in the default location, a full path to the library will need to be given to the CREATE FUNCTION commands:

CREATE FUNCTION handler() RETURNS LANGUAGE_HANDLER
 LANGUAGE C AS '/full/path/to/python', 'pl_handler';
CREATE FUNCTION validator(oid) RETURNS VOID
 LANGUAGE C AS '/full/path/to/python', 'pl_validator';
CREATE FUNCTION inline(INTERNAL) RETURNS VOID
 LANGUAGE C AS '/full/path/to/python', 'pl_inline';

Configuration

pg-python does not require any additional configuration once installed. However, much initialization overhead can be eliminated by preloading the extension using the shared_preload_libraries configuration parameter.

Specifically:

shared_preload_libraries = 'python'

Using this will cause Python to be initialized when Postgres is started.

Local Initialization

When Python is loaded, the init.py file in the data directory will be executed if it exists. The contents of this file will be executed in a new module named __pg_init__. The module is stored in sys.modules, but primarily for identifying that an init.py file was loaded.

The primary purpose of the initialization file is to allow modules to be preloaded when the server is started. Writing functions that depend on objects created by init.py should be avoided.

For init.py to provide any savings, it should be used in conjunction with the shared_preload_libraries configuration parameter.

Note

When init.py is loaded, database access is prohibited.

Managing Multiple Versions

Warning

This section covers advanced material.

In some situations, it may be necessary to have multiple builds of pg-python installed in the same PostgreSQL installation for upgrade purposes. When such cases arise, using a distinct name for the language is necessary.

There are two routes that can be taken. The first is to rename the existing language making room for the new one, and the second is to use a different name for the new version. The best path depends on the situation.

Renaming the Existing Language

Renaming the existing language is the proper choice when there is an incompatibility between the existing language and the new target language. This situation demands that functions be incrementally ported to the new version as time permits.

Note

Renaming the existing language may require restart of the cluster.

The first step in renaming the existing language is to copy the original python.so so that it’s name is distinct from the one that is going to be installed. This can be done while the cluster is running:

cd $PREFIX/lib/postgresql/
cp python.so python31.so

The second step is to create the new language object. It is recommended to name it after the specific version of Python being used:

BEGIN;
CREATE SCHEMA __python31__;
SET search_path = __python31__;
CREATE FUNCTION handler() RETURNS LANGUAGE_HANDLER
 LANGUAGE C AS 'python31', 'pl_handler';
CREATE FUNCTION validator(oid) RETURNS VOID
 LANGUAGE C AS 'python31', 'pl_validator';
COMMIT;

-- For 9.0 and greater.
BEGIN;
SET search_path = __python31__;
CREATE FUNCTION inline(INTERNAL) RETURNS VOID
 LANGUAGE C AS 'python31', 'pl_inline';
CREATE LANGUAGE python31
 HANDLER handler INLINE inline VALIDATOR validator;
COMMIT;

-- For versions before 9.0.
BEGIN;
SET search_path = __python31__;
CREATE LANGUAGE python31
 HANDLER handler VALIDATOR validator;
COMMIT;

Next, the existing functions need to have their language updated:

UPDATE pg_catalog.pg_proc
SET prolang = (SELECT oid FROM pg_language WHERE lanname = 'python31')
WHERE prolang = (SELECT oid FROM pg_language WHERE lanname = 'python');

Warning

It is best not to have other backends running while the above command is running.

And finally, the old language should be removed in order to make room for the new default:

SET search_path = __python__;
DROP FUNCTION handler();
DROP FUNCTION validator(oid);
DROP FUNCTION inline(internal);
RESET search_path;
DROP SCHEMA __python__;

With those steps complete, the language has been renamed, and the new language may be installed using the steps documented in Compilation and Database Installation.

Using a Custom Name for the New Language

Using a custom name for the new language is the proper choice when necessary functionality is exclusively available in a past version of Python. Such cases are likely transient, but when they occur, they are best handled as an exception.

Using a custom name for the language is significantly easier renaming an existing language. All that is required is that the built python.so file be manually into the $PREFIX/lib/postgresql directory under a new name:

cp python.so $PREFIX/lib/postgresql/python31.so

Once complete, database installation can then be performed with a slight modification:

BEGIN;
CREATE SCHEMA __python31__;
SET search_path = __python31__;
CREATE FUNCTION handler() RETURNS LANGUAGE_HANDLER
 LANGUAGE C AS 'python31', 'pl_handler';
CREATE FUNCTION validator(oid) RETURNS VOID
 LANGUAGE C AS 'python31', 'pl_validator';
COMMIT;

-- For 9.0 and greater
BEGIN;
CREATE FUNCTION inline(INTERNAL) RETURNS VOID
 LANGUAGE C AS 'python31', 'pl_inline';
CREATE LANGUAGE python31
 HANDLER handler INLINE inline VALIDATOR validator;
COMMIT;

-- For versions before 9.0
BEGIN;
CREATE LANGUAGE python31
 HANDLER handler VALIDATOR validator;
COMMIT;

Complete. The python31 language will be ready for use alongside any others.