Skip to content
multicorn

multicorn

multicorn : Fetch foreign data in Python in your PostgreSQL server.

Overview

IDExtensionPackageVersionCategoryLicenseLanguage
8510
multicorn
multicorn
3.2
FDW
PostgreSQL
C
AttributeHas BinaryHas LibraryNeed LoadHas DDLRelocatableTrusted
--s-d--
No
Yes
No
Yes
no
no
Relationships
See Also
wrappers
odbc_fdw
jdbc_fdw
pgspider_ext
mysql_fdw
db2_fdw
mongo_fdw
redis_fdw

Packages

TypeRepoVersionPG Major CompatibilityPackage PatternDependencies
EXT
PGDG
3.2
18
17
16
15
14
multicorn-
RPM
PGDG
3.2
18
17
16
15
14
multicorn2_$v-
DEB
PIGSTY
3.2
18
17
16
15
14
postgresql-$v-multicornpython3-multicorn
Linux / PGPG18PG17PG16PG15PG14
el8.x86_64
PGDG 3.2
PGDG 3.2
PGDG 3.2
PGDG 3.2
PGDG 3.2
el8.aarch64
PGDG 3.2
PGDG 3.2
PGDG 3.2
PGDG 3.2
PGDG 3.2
el9.x86_64
PGDG 3.2
PGDG 3.2
PGDG 3.2
PGDG 3.2
PGDG 3.2
el9.aarch64
PGDG 3.2
PGDG 3.2
PGDG 3.2
PGDG 3.2
PGDG 3.2
el10.x86_64
PGDG 3.2
PGDG 3.2
PGDG 3.2
PGDG 3.2
PGDG 3.2
el10.aarch64
PGDG 3.2
PGDG 3.2
PGDG 3.2
PGDG 3.2
PGDG 3.2
d12.x86_64
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
d12.aarch64
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
d13.x86_64
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
d13.aarch64
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
u22.x86_64
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
u22.aarch64
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
u24.x86_64
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
u24.aarch64
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
u26.x86_64
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
u26.aarch64
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PIGSTY 3.2
PackageVersionOSORGSIZEFile URL
multicorn2_183.2el8.x86_64pgdg138.0 KiBmulticorn2_18-3.2-1PGDG.rhel8.x86_64.rpm
multicorn2_183.1el8.x86_64pgdg135.5 KiBmulticorn2_18-3.1-1PGDG.rhel8.x86_64.rpm
multicorn2_183.2el8.aarch64pgdg136.3 KiBmulticorn2_18-3.2-1PGDG.rhel8.aarch64.rpm
multicorn2_183.1el8.aarch64pgdg133.9 KiBmulticorn2_18-3.1-1PGDG.rhel8.aarch64.rpm
multicorn2_183.2el9.x86_64pgdg134.6 KiBmulticorn2_18-3.2-3PGDG.rhel9.8.x86_64.rpm
multicorn2_183.2el9.x86_64pgdg134.6 KiBmulticorn2_18-3.2-1PGDG.rhel9.x86_64.rpm
multicorn2_183.1el9.x86_64pgdg111.0 KiBmulticorn2_18-3.1-1PGDG.rhel9.x86_64.rpm
multicorn2_183.2el9.aarch64pgdg133.8 KiBmulticorn2_18-3.2-3PGDG.rhel9.8.aarch64.rpm
multicorn2_183.2el9.aarch64pgdg133.5 KiBmulticorn2_18-3.2-1PGDG.rhel9.aarch64.rpm
multicorn2_183.1el9.aarch64pgdg110.0 KiBmulticorn2_18-3.1-1PGDG.rhel9.aarch64.rpm
multicorn2_183.2el10.x86_64pgdg135.2 KiBmulticorn2_18-3.2-3PGDG.rhel10.2.x86_64.rpm
multicorn2_183.2el10.x86_64pgdg135.5 KiBmulticorn2_18-3.2-1PGDG.rhel10.x86_64.rpm
multicorn2_183.1el10.x86_64pgdg133.0 KiBmulticorn2_18-3.1-1PGDG.rhel10.x86_64.rpm
multicorn2_183.2el10.aarch64pgdg134.4 KiBmulticorn2_18-3.2-3PGDG.rhel10.2.aarch64.rpm
multicorn2_183.2el10.aarch64pgdg134.6 KiBmulticorn2_18-3.2-1PGDG.rhel10.aarch64.rpm
multicorn2_183.1el10.aarch64pgdg131.9 KiBmulticorn2_18-3.1-1PGDG.rhel10.aarch64.rpm
postgresql-18-multicorn3.2d12.x86_64pigsty81.5 KiBpostgresql-18-multicorn_3.2-1PIGSTY~bookworm_amd64.deb
postgresql-18-multicorn3.2d12.aarch64pigsty79.7 KiBpostgresql-18-multicorn_3.2-1PIGSTY~bookworm_arm64.deb
postgresql-18-multicorn3.2d13.x86_64pigsty82.5 KiBpostgresql-18-multicorn_3.2-1PIGSTY~trixie_amd64.deb
postgresql-18-multicorn3.2d13.aarch64pigsty80.8 KiBpostgresql-18-multicorn_3.2-1PIGSTY~trixie_arm64.deb
postgresql-18-multicorn3.2u22.x86_64pigsty87.7 KiBpostgresql-18-multicorn_3.2-1PIGSTY~jammy_amd64.deb
postgresql-18-multicorn3.2u22.aarch64pigsty86.9 KiBpostgresql-18-multicorn_3.2-1PIGSTY~jammy_arm64.deb
postgresql-18-multicorn3.2u24.x86_64pigsty85.5 KiBpostgresql-18-multicorn_3.2-1PIGSTY~noble_amd64.deb
postgresql-18-multicorn3.2u24.aarch64pigsty84.3 KiBpostgresql-18-multicorn_3.2-1PIGSTY~noble_arm64.deb
postgresql-18-multicorn3.2u26.x86_64pigsty84.8 KiBpostgresql-18-multicorn_3.2-1PIGSTY~resolute_amd64.deb
postgresql-18-multicorn3.2u26.aarch64pigsty83.7 KiBpostgresql-18-multicorn_3.2-1PIGSTY~resolute_arm64.deb

Source

Install

Make sure PGDG repo available:

pig repo add pgdg -u    # add pgdg repo and update cache

Install this extension with pig:

pig install multicorn;		# install via package name, for the active PG version

pig install multicorn -v 18;   # install for PG 18
pig install multicorn -v 17;   # install for PG 17
pig install multicorn -v 16;   # install for PG 16
pig install multicorn -v 15;   # install for PG 15
pig install multicorn -v 14;   # install for PG 14

Create this extension with:

CREATE EXTENSION multicorn;

Usage

Sources: README, CHANGELOG

Multicorn2 allows you to write Foreign Data Wrappers in Python. You implement a Python class that inherits from multicorn.ForeignDataWrapper, and Multicorn handles bridging it to PostgreSQL’s FDW interface. Version 3.2 is tested with PostgreSQL 14-18 and Python 3.9-3.13, though upstream recommends Python 3.10-3.12 for near-term distro compatibility.

Define a Python FDW Class

Create a Python module (e.g., myfdw.py) accessible to the PostgreSQL process:

from multicorn import ForeignDataWrapper

class MyFDW(ForeignDataWrapper):
    def __init__(self, options, columns):
        super().__init__(options, columns)
        self.options = options
        self.columns = columns

    def execute(self, quals, columns):
        """Yield rows as dictionaries. quals contains WHERE pushdown info."""
        yield {"id": 1, "name": "example"}

    def insert(self, new_values):
        """Handle INSERT operations."""
        pass

    def update(self, old_values, new_values):
        """Handle UPDATE operations."""
        pass

    def delete(self, old_values):
        """Handle DELETE operations."""
        pass

Create Server and Foreign Table

CREATE EXTENSION multicorn;

CREATE SERVER multicorn_srv FOREIGN DATA WRAPPER multicorn
  OPTIONS (wrapper 'myfdw.MyFDW');

CREATE FOREIGN TABLE my_table (
  id integer,
  name text
)
SERVER multicorn_srv
OPTIONS (
  option1 'value1'
);

SELECT * FROM my_table;

The wrapper option specifies the fully qualified Python class name. Any additional options are passed to the class constructor’s options parameter.

Built-in FDW Examples

Multicorn ships with several example FDW implementations that can be used directly or as reference:

  • CsvFdw – read CSV files
  • ProcessFdw – execute system commands and parse output
  • GCalFdw – access Google Calendar
  • ImapFdw – query IMAP mailboxes
  • RssFdw – read RSS/Atom feeds
CREATE SERVER csv_srv FOREIGN DATA WRAPPER multicorn
  OPTIONS (wrapper 'multicorn.csvfdw.CsvFdw');

CREATE FOREIGN TABLE csvtest (
  col1 text,
  col2 text
)
SERVER csv_srv
OPTIONS (
  filename '/tmp/data.csv',
  skip_header '1',
  delimiter ','
);

Version Notes

Multicorn 3.2 adds basic OFFSET/LIMIT pushdown and LDAP paging support, and fixes LDAP right-parenthesis escaping. Upstream 3.1 added PostgreSQL 18 and Python 3.13 support while dropping PostgreSQL versions before 14.

Caveats

Multicorn2 and PL/Python are incompatible in the same PostgreSQL database on Python 3.12 due to CPython limitations. They can be installed on the same system, but avoid enabling both in one database.

Last updated on