Foreign data wrappers: PostgreSQL's secret weapon?
splitgraph.com
splitgraph.com
We have most of our data in a Postgres DB with a layout we like: multiple "core" or low-level schemas and a higher-level API schema which is how all other services interact with it (reads and writes). We also have a few much smaller but very important additional SQL DBs (Postgres and MySQL). There's no good reason all this data can't or shouldn't live together (it's really all one "service"), and plenty ways it would make our architecture and dev work simpler (we join across them all the time).
So, I figure for each smaller DB, I could expose it with an FDW from the DB we like, and use those tables in that DB's API schema. Once we settle on good API & usage patterns there, I would then copy data from the FDW tables into local tables, update references in the API schema, and finally drop the FDW and decom the other DB's.
Is that sane? I know the usual caveats about order-of-operations, potentially writing to two places for some time to ensure no data is lost, etc. and am not worried about those.
In my case I was moving account number information between iSeries db2 and an ArcGIS instance.
As I was trying to find a reference to when SQL Anywhere introduced proxy tables, I came across a post [1] that discussed the speed improvement in proxy table bulk loads introduced in SQL Anywhere 11. It is reasonable to do the same with PostgreSQL's FDWs if the underlying query optimizer detects when a bulk load technique should be used. Sounds like a good experiment to run.
[1] http://sqlanywhere.blogspot.com/2010/01/omigosh-proxy-tables...
But the title in hn is off-putting - agree it feels like misleading marketing.
And yeah, I agree it'd be nicer to have an honest to goodness breakdown of FDWs. Where they came from, how they work under the hood, how to set one up from the bottom up, what the tradeoffs and pitfalls are, etc.
Though I wouldn't be bothered if such an article served as content marketing for some postgres company or engineering brand myself. Someone's gotta find the writing - it's hard work.
Our goal in building Splitgraph is to improve the data science ecosystem, so we're doing all we can to gain some early adopters for what we really think is a useful tool. For what it's worth, we are trying to keep a balance in our blog posts between obvious content marketing and useful technical content, e.g. this article where we discuss building Docker containers with Makefiles. [0]
And a question for any postgres people: say I have two distinct databases, but now need to join across them. What's best practice here?
If you use `SET enable_nestloop=off`, this will disable them for that session and use alternative strategies (like hash or merge join) which might be faster.
[0] https://www.postgresql.org/docs/current/runtime-config-query...
[1] https://www.splitgraph.com/docs/large-datasets/layered-query...
EDIT: You've probably already tried that if you're following the docs, since they recommend it -- https://www.postgresql.org/docs/current/rules-materializedvi...
you didnt answer your own question. is it a secret weapon?
In particular, we really like the feature of foreign data wrappers, and it forms the basis of one of our core abstractions ("mounting" upstream data) [0]. We've added a lot of scaffolding to make writing and using FDWs easier with a Splitgraph engine (which is just Postgres with the Splitgraph library loaded into it). You can also IMPORT from upstream sources using Splitfiles, to pack the data into a versioned “image” (analogous to Dockerfiles and docker images).
As for whether they're a secret weapon? Well, they're not so secret, but it does seem like they're underutilized considering the power they grant. We certainly like them.
[0] I wrote a post today about how we use a Socrata FDW to "mount" 40k+ government datasets, making them all available via SQL: https://www.splitgraph.com/blog/40k-sql-datasets
They are indeed powerful and underutilized. They also go by different names in other RDBMSes (proxy tables, linked servers, remote tables, virtual tables, etc.). If I remember correctly, SQL Anywhere 6 released in 1998 was the first rich implementation [1] of "proxy tables" to "remote servers" and Microsoft soon followed with "Linked Servers". The embedded database libraries (Apache Derby and SQLite) added rich APIs/SPIs to create virtual table plugins like SQLite's FTS.
Using remote tables for federated queries across heterogenous data sources, and for access to non-relational data sources, is a well established technique and a powerful "weapon" for those who know how to wield it. It might not be PostgreSQL's secret weapon but it may very well be Splitgraph's.
[1] http://dcx.sap.com/index.html#1001/en/dbwnen10/wn-remote-new...
> However, to access non-Oracle systems you must use Oracle Heterogeneous Services.
[1] https://docs.oracle.com/cd/A57673_01/DOC/server/doc/SQL73/ch...
I haven't used it myself but it's pretty cool that it's out there.
[0] https://www.splitgraph.com/docs/concepts/objects
[1] https://tech.marksblogg.com/billion-nyc-taxi-rides-postgresq...
To what extent would this be noticeable to applications?
Could this be an interesting scaling/reliability strategy in some circumstances?
But this is actually one of the cool use cases we built Splitgraph for: you can mount a bunch of remote databases (doesn't have to be PG, can be Mongo/MySQL etc), Splitgraph images and even remote datasets like Socrata[1] into a single workspace and run e.g. JOINs between them. We optimize for the OLAP (read-only) use case and have a special FDW for querying remote Splitgraph images (we call this layered querying [0]). It downloads required regions of the table in the background, completely seamlessly to the client application. So you can spin up a lightweight Splitgraph engine at the edge and point a PostgreSQL client to it. This will let you satisfy read-only queries to huge remote datasets with a small local cache.
Re: compatibility, we have tested this setup with various analytics software and PostgreSQL clients like DBeaver/Metabase/dbt[2] and it works pretty well.
[0] https://www.splitgraph.com/docs/large-datasets/layered-query...
[1] https://www.splitgraph.com/blog/40k-sql-datasets
[2] https://www.splitgraph.com/product/splitgraph/integrations
FDWs aren't really that layperson-friendly: to set one up, you need to run a lot of SQL boilerplate like CREATE FOREIGN SERVER, CREATE USER MAPPING and CREATE FOREIGN TABLE. We wanted to make them more accessible through our sgr mount [2] command and snapshottable via Splitfiles (e.g. [3]).
The point about data types changing is also a good one. Where the foreign data wrapper doesn't implement IMPORT FOREIGN SCHEMA [4] through introspection on the foreign database side, you have to enumerate all columns and types in CREATE FOREIGN TABLE. If a column on the remote table goes away, the FDW might still query it and cause runtime errors.
[0] https://wiki.postgresql.org/wiki/Future_of_storage
[1] https://github.com/citusdata/postgres_vectorization_test
[2] https://www.splitgraph.com/docs/sgr/data-import-export/mount
[3] https://www.splitgraph.com/docs/ingesting-data/socrata#split...
[4] https://www.postgresql.org/docs/current/sql-importforeignsch...
At its simplest, the FDW can just return all tuples from the remote database without filtering them (letting the local DB run filtering). But more advanced FDWs like postgres_fdw[0] can push down qualifiers and joins to the remote database. postgres_fdw even runs EXPLAIN on the remote instance and parses its output -- essentially letting the local and the foreign query planners collaborate on execution.
[0] https://www.postgresql.org/docs/current/postgres-fdw.html#id...
I mean I love FDWs, especially how easy it is to write one... But this is an issue I've run into.
For a lot of people that’s probably not a net negative.
Something like this has happened to me when reading from a csv file.
In this case pg will show an error and not read any rows from the fdw.