無料のベクトルデータベースとして Fly Postgres を使う【pgvector】

# はじめに

[fly.io](https://fly.io) では PostgreSQL を使うことができ, [無料枠](https://fly.io/docs/about/pricing/)があります.

https://fly.io/docs/postgres

本記事では, __Fly Postgres__ をベクトルデータベースとして使えるようにする手順を説明します.


# まず docker image を作る

PostgreSQL をベクトルデータベースとして使うには, __pgvector__ という拡張をインストールする必要があります.

https://github.com/pgvector/pgvector

そこで, Fly Postgres で使われている [flyio/postgres-flex](https://github.com/fly-apps/postgres-flex) をベースイメージとし, [pgvector をインストール](https://github.com/pgvector/pgvector#apt)したカスタムイメージを作成します.

```dockerfile:Dockerfile
ARG PG_MAJOR=17
FROM flyio/postgres-flex:${PG_MAJOR}
ARG PG_MAJOR

RUN apt-get update \
    && apt-get install -y --no-install-recommends postgresql-${PG_MAJOR}-pgvector \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# 以下はお好みで日本語用の設定
RUN echo "ja_JP.UTF-8 UTF-8" > /etc/locale.gen && locale-gen
ENV LANG ja_JP.UTF-8

ENV TZ Asia/Tokyo
```

docker image を build して, Docker レジストリに push します. [^1]

[^1]: あらかじめ [Docker Hub](https://hub.docker.com) などのレジストリのアカウント作成や,  `docker login` が必要です

```console
$ PG_MAJOR=17  # Postgres のメジャーバージョンを指定
$ docker image build . -t <your-name>/fly-pgvector:$PG_MAJOR --build-arg PG_MAJOR=$PG_MAJOR
$ docker image push <your-name>/fly-pgvector:$PG_MAJOR
```


# Fly Postgres クラスタを立てる
push したカスタムイメージを使って, [Fly Postgres クラスタを立てます](https://fly.io/docs/postgres/getting-started/create-pg-cluster). [^2]

[^2]: あらかじめ [`flyctl` のインストールやサインイン](https://fly.io/docs/hands-on/install-flyctl) が必要です

```console
$ fly pg create --image-ref <your-name>/fly-pgvector:$PG_MAJOR
automatically selected personal organization: <your-org>
Some regions require a paid plan (bom, fra, maa).
See https://fly.io/plans to set up a plan.

? Select region: Tokyo, Japan (nrt)
? Select configuration: Development - Single node, 1x shared CPU, 256MB RAM, 1GB disk
? Scale single node pg to zero after one hour? No
Creating postgres cluster in organization personal
Creating app...
Setting secrets on app <pg-app-name>...
Provisioning 1 of 1 machines with image <your-name>/fly-pgvector:$PG_MAJOR
Waiting for machine to start...
Machine 123456abcdef is created
==> Monitoring health checks
  Waiting for 123456abcdef to become healthy (started, 3/3)

Postgres cluster <pg-app-name> created
  Username:    postgres
  Password:    ********
  Hostname:    <pg-app-name>.internal
  Flycast:     *:*:*:*:*:*:*
  Proxy port:  5432
  Postgres port:  5433
  Connection string: postgres://postgres:********@<pg-app-name>.flycast:5432

Save your credentials in a secure place -- you won't be able to see them again!

Connect to postgres
Any app within the <your-org> organization can connect to this Postgres using the above connection string

Now that you've set up Postgres, here's what you need to understand: https://fly.io/docs/postgres/getting-started/what-you-should-know/
```

これで Postgres クラスタが立ち上がりました. 以下のコマンドでも確認できます.

```console
$ fly pg ls
NAME            OWNER           STATUS          LATEST DEPLOY
<pg-app-name>   personal        deployed
```


# ベクトルデータベース化する

まず [Postgres データベースに接続](https://fly.io/docs/postgres/connecting/connecting-with-flyctl)します.

```console
$ fly pg connect -a <pg-app-name>
Connecting to *:*:*:*:*:*:*:*... complete
psql (15.3 (Debian 15.3-1.pgdg110+1))
"help"でヘルプを表示します。

postgres=#
```

次に [vector 拡張を有効化](https://github.com/pgvector/pgvector/tree/master#getting-started)します.

```sql
postgres=# create extension vector;
CREATE EXTENSION

postgres=# select * from pg_extension where extname = 'vector';
  oid  | extname | extowner | extnamespace | extrelocatable | extversion | extconfig | extcondition
-------+---------+----------+--------------+----------------+------------+-----------+--------------
 16513 | vector  |       10 |         2200 | t              | 0.4.2      |           |
(1 行)
```

これでベクトルデータベース化できました.


# Embedding などするときの接続方法

[ローカル環境へのポートフォワード](https://fly.io/docs/postgres/connecting/connecting-with-flyctl)は下記で可能です.

```console
$ fly proxy 15432:5432 -a <pg-app-name>
```

`localhost:15432` で接続できるようになります.

```console
$ psql postgres://postgres:<password>@localhost:15432
```

インターネット経由で Postgres に接続したい場合は, 下記の公式ドキュメントに従って設定してください.

https://fly.io/docs/postgres/connecting/connecting-external


# 参考
LangChain で Postgres を使うときは, 下記の公式ドキュメントを参照.

https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/pgvector