現在、PostgreSQLデータベースがあり、いくつかのPerlバインディングを介してデータベースにアクセスし、データベースにアクセスして、Perlタイプへの応答をマーシャリングします。これは問題なく動作しますが、さまざまな理由でPerlに不満を持っています。私たちが検討してきたオプションの1つは、このAPIの作業の大部分をplpgsql
ストアドプロシージャとしてデータベース自体に移動することです。
簡単な例
たとえば、データベースに次のものがあるとします。
-- This matches our 'Entity::Artist' object
CREATE TYPE loaded_artist (
artist_id uuid,
revision_id integer,
artist_tree_id integer,
name text,
sort_name text,
artist_type_id integer,
-- etc
);
-- This gets the latest 'master' version of an artist and joins in basic data
-- from the artist tree
CREATE FUNCTION get_latest_artist_by_mbid(in_mbid UUID)
RETURNS SETOF loaded_artist AS $$
BEGIN
RETURN QUERY
SELECT
artist_id, revision_id, artist_tree_id, name.name,
sort_name.name AS sort_name, artist_type_id
FROM artist
JOIN artist_revision USING (artist_id)
JOIN artist_tree USING (artist_tree_id)
JOIN artist_data USING (artist_data_id)
WHERE artist.master_revision_id = revision_id
AND artist_id = in_mbid;
END;
$$ LANGUAGE 'plpgsql';
これで、現在のPerl APIを簡略化して、効果的に次のようにすることができます。
package Data::Artist;
sub get_latest_by_mbid {
my ($self, $mbid) = @_;
return $self->new_from_row(
$self->sql->select_single_row_hash(
'SELECT * FROM get_latest_artist_by_mbid(?)',
$mbid));
}
これは賢明ですか?
額面では、私はこれが好きです。我々:
- Perlから離れますが、別の言語にコミットしないでください。これは、将来的に実際のアプリケーションをPythonなどに移行でき、APIの大部分がすでに完了していることを意味します。
- 次のようなものを指定することにより、PostgreSQLから追加の型安全性を取得します
RETURNS SETOF loaded_artist
- PGTAPを介した単体テストなどはまだあります。
いくつかの欠点があります。
- データベース内の関数を置き換える必要があるため、開発サイクルが短縮される可能性があります。世界の終わりではありませんが、これにより、以前は存在しなかった「コンパイル」ステップがワークフローに効果的に導入されます。
- 潜在的に難しいバージョン管理ですが、確かにそれを行う方法があります
誰かがこのような仕事をしましたか?あなたはそれを奨励しますか、それとも危険に満ちていましたか?
脚注:私たちのケースについてもう少し
これはオープンソースのウェブサイト用です。データベースのダンプを配布して、PostgreSQLデータベースにインポートできるようにします。PGからすぐに移行する予定はないため、データベースにとらわれない決定は実際には当てはまりません。私たちは非常に小さなチーム(2人の有料開発者、より多くのオープンソース貢献者)であり、これにより、展開戦略に関して非常に柔軟になります。