multicorn

Fetch foreign data in Python in your PostgreSQL server.

Overview

PackageVersionCategoryLicenseLanguage
multicorn3.2FDWPostgreSQLC
IDExtensionBinLibLoadCreateTrustRelocSchema
8510multicornNoYesNoYesNoNo-
Relatedwrappers odbc_fdw jdbc_fdw pgspider_ext mysql_fdw db2_fdw mongo_fdw redis_fdw

Version

TypeRepoVersionPG VerPackageDeps
EXTPGDG3.21817161514multicorn-
RPMPGDG3.21817161514multicorn2_$v-
OS / PGPG18PG17PG16PG15PG14
el8.x86_64
el8.aarch64
el9.x86_64
el9.aarch64
el10.x86_64
el10.aarch64
d12.x86_64PGDG MISSPGDG MISSPGDG MISSPGDG MISSPGDG MISS
d12.aarch64PGDG MISSPGDG MISSPGDG MISSPGDG MISSPGDG MISS
d13.x86_64PGDG MISSPGDG MISSPGDG MISSPGDG MISSPGDG MISS
d13.aarch64PGDG MISSPGDG MISSPGDG MISSPGDG MISSPGDG MISS
u22.x86_64PGDG MISSPGDG MISSPGDG MISSPGDG MISSPGDG MISS
u22.aarch64PGDG MISSPGDG MISSPGDG MISSPGDG MISSPGDG MISS
u24.x86_64PGDG MISSPGDG MISSPGDG MISSPGDG MISSPGDG MISS
u24.aarch64PGDG MISSPGDG MISSPGDG MISSPGDG MISSPGDG MISS

Install

You can install multicorn directly. First, make sure the PGDG repository is added and enabled:

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

Install the extension using pig or apt/yum/dnf:

pig install multicorn;          # Install for current active PG version
pig ext install -y multicorn -v 18  # PG 18
pig ext install -y multicorn -v 17  # PG 17
pig ext install -y multicorn -v 16  # PG 16
pig ext install -y multicorn -v 15  # PG 15
pig ext install -y multicorn -v 14  # PG 14
dnf install -y multicorn2_18       # PG 18
dnf install -y multicorn2_17       # PG 17
dnf install -y multicorn2_16       # PG 16
dnf install -y multicorn2_15       # PG 15
dnf install -y multicorn2_14       # PG 14

Create Extension:

CREATE EXTENSION multicorn;

Usage

multicorn: Fetch foreign data in Python in your PostgreSQL server

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.

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 ','
);

Last Modified 2026-03-12: add pg extension catalog (95749bf)