Heroku Postgres への接続
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2024年04月29日(月)
Table of Contents
Heroku Postgres には、さまざまなプログラミング言語およびフレームワークからアクセスできます。
Heroku Postgres および SSL
Heroku Postgres では、TLS v1.2 以上を使用する SSL 接続が必要です。
ほとんどのクライアントはデフォルトで SSL 経由で接続しますが、Postgres 接続上で sslmode=require
パラメータを設定することが必要になる場合があります。このパラメータは、環境設定を直接編集するのではなく、コードで追加してください。特に、Java または Node.js クライアントを使用している場合は、SSL を適用することをお勧めします。
接続のアクセス許可
Heroku Postgres ユーザーは、データベースのスーパーユーザー以外のすべての権限が認められています。これらには、SELECT
、INSERT
、UPDATE
、DELETE
、TRUNCATE
、REFERENCES
、TRIGGER
、CREATE
、CONNECT
、TEMPORARY
、EXECUTE
、および USAGE
と、制限された ALTER
および GRANT
の権限があります。
Heroku では、ユーザーとデータベースを自動的に作成するために、次の SQL を実行します。
CREATE ROLE user_name;
ALTER ROLE user_name WITH LOGIN PASSWORD 'password' NOSUPERUSER NOCREATEDB NOCREATEROLE;
CREATE DATABASE database_name OWNER user_name;
REVOKE ALL ON DATABASE database_name FROM PUBLIC;
GRANT CONNECT ON DATABASE database_name TO user_name;
GRANT ALL ON DATABASE database_name TO user_name;
複数のスキーマ
Heroku Postgres では複数のスキーマがサポートされており、作成できるスキーマの数に制限はありません。
データベースで複数のスキーマを使用する最も一般的なユースケースは、お客様ごとに独自のスキーマが用意されている Software as a Service アプリケーションを構築することです。このテクニックは魅力的に見えますが、操作上に問題のある多数の事例を引き起こしているので決してお勧めしません。たとえば、適度な数のスキーマ (>50) でも、Heroku のデータベーススナップショットツールである PG バックアップのパフォーマンスに大きな影響を与えることがあります。
外部接続 (ingress)
Heroku ランタイムに使用できることに加え、Heroku Postgres データベースは、ローカルコンピューターや他の箇所で実行しているクライアントから直接アクセスできます。
すべての接続は SSL を必要とします: sslmode=require
。
2 つの方法のいずれかで、PG 接続文字列を取得できます。heroku pg:credentials:url
コマンドを実行できます。
$ heroku pg:credentials:url DATABASE
Connection info string:
"dbname=dee932clc3mg8h host=ec2-123-73-145-214.compute-1.amazonaws.com port=6212 user=user3121 password=98kd8a9 sslmode=require"
また、接続文字列はアプリの環境設定として公開されます。
$ heroku config | grep HEROKU_POSTGRESQL
HEROKU_POSTGRESQL_YELLOW_URL: postgres://user3123:passkja83kd8@ec2-117-21-174-214.compute-1.amazonaws.com:6212/db982398
Java での接続
ご使用の Java フレームワークに応じて、Heroku Postgres データベースへの接続を作成するさまざまな方法があります。「Java を使用して Heroku でリレーショナルデータベースに接続する」の記事で説明されているように、ほとんどの場合、環境変数 JDBC_DATABASE_URL
は直接使用できます。次に例を示します。
private static Connection getConnection() throws URISyntaxException, SQLException {
String dbUrl = System.getenv("JDBC_DATABASE_URL");
return DriverManager.getConnection(dbUrl);
}
JDBC URL を (通常は、カスタム buildpack が使用されているために) 使用できない場合は、DATABASE_URL
環境 URL を使用して接続情報を特定する必要があります。いくつかの例を下に示します。
デフォルトでは、Heroku ではプロパティ sslmode=require
をグローバルに設定することによって、PostgreSQL JDBC ドライバーに対して SSL を有効にしようとします。JDBC URL を自分で (たとえば、DATABASE_URL
を解析することによって) 作成している場合は、このパラメータを明示的に追加することをお勧めします。
Postgres JDBC ドライバーバージョン 9.2 以上のバージョンを使用することも重要です。たとえば、Maven では pom.xml
に次の行を追加します。
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.1</version>
</dependency>
ここで概説するすべての接続方法の例は、https://github.com/heroku/devcenter-java-database にある GitHub で入手できます。
JDBC
DATABASE_URL
環境変数を解析することにより、Heroku Postgres への JDBC 接続を作成します。
private static Connection getConnection() throws URISyntaxException, SQLException {
URI dbUri = new URI(System.getenv("DATABASE_URL"));
String username = dbUri.getUserInfo().split(":")[0];
String password = dbUri.getUserInfo().split(":")[1];
String dbUrl = "jdbc:postgresql://" + dbUri.getHost() + ':' + dbUri.getPort() + dbUri.getPath() + "?sslmode=require";
return DriverManager.getConnection(dbUrl, username, password);
}
Spring/XML
次の Spring XML 設定スニペットでは、DATABASE_URL
から BasicDataSource
を作成します。これは、Hibernate、JPA などで使用できます。
<bean class="java.net.URI" id="dbUrl">
<constructor-arg value="#{systemEnvironment['DATABASE_URL']}"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="url" value="#{ 'jdbc:postgresql://' + @dbUrl.getHost() + ':' + @dbUrl.getPort() + @dbUrl.getPath() + '?sslmode=require' }"/>
<property name="username" value="#{ @dbUrl.getUserInfo().split(':')[0] }"/>
<property name="password" value="#{ @dbUrl.getUserInfo().split(':')[1] }"/>
</bean>
Spring/Java
または、Spring で BasicDataSource
の設定に Java を使用できます。
@Configuration
public class MainConfig {
@Bean
public BasicDataSource dataSource() throws URISyntaxException {
URI dbUri = new URI(System.getenv("DATABASE_URL"));
String username = dbUri.getUserInfo().split(":")[0];
String password = dbUri.getUserInfo().split(":")[1];
String dbUrl = "jdbc:postgresql://" + dbUri.getHost() + ':' + dbUri.getPort() + dbUri.getPath() + "?sslmode=require";
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setUrl(dbUrl);
basicDataSource.setUsername(username);
basicDataSource.setPassword(password);
return basicDataSource;
}
}
Heroku Postgres アドオンの DATABASE_URL
はこの命名規則に従います。
postgres://<username>:<password>@<host>/<dbname>
ただし、Postgres JDBC ドライバーは次の規則を使用します。
jdbc:postgresql://<host>:<port>/<dbname>?sslmode=require&user=<username>&password=<password>
jdbc:postgresql
の最後に ql
が追加されていることに注意してください。この違いのために、Java クラスまたは Spring XML 設定内の jdbc:postgresql
にスキームをハードコーディングする必要があります。
リモート接続
メンテナンスおよびデバッグの目的で、Heroku Postgres データベースにリモートで接続できます。ただし、そうするには、SSL 接続を使用する必要があります。JDBC 接続の URL には、次の URL パラメータを含める必要があります。
sslmode=require
sslmode=require
を省略し、本番プランのデータベースに接続しようとすると、接続エラーが表示されます。
このパラメータは、環境設定を直接編集するのではなく、コードで追加する必要があります。フェイルオーバーなどの自動化されたイベントによって環境設定が変更され、編集内容が上書きされる場合があります。
詳細については、ここをクリックし、「Java を使用して Heroku でリレーショナルデータベースに接続する」に関する Dev Center の記事を参照してください。
Ruby での接続
Ruby アプリケーションで PostgreSQL をデータベースとして使用するには、Gemfile
に pg
gem を含める必要があります。
gem 'pg'
bundle install
を実行して、すべての依存関係をダウンロードして解決します。
pg
gem を使用して Heroku dyno から Postgres データベースに接続し、設定またはコードで sslmode
を指定していない場合、この gem では sslmode: prefer
がデフォルトで使用されます。sslmode: prefer
を使用する場合、Postgres データベースで SSL の使用が強制されていれば、その接続は機能できます。
Rails での接続
Rails アプリケーションが Heroku にデプロイされると、database.yml
ファイルがアプリケーション用に自動的に生成されます。それにより、PostgreSQL 接続を使用し、DATABASE_URL
によって指定されたデータベースに接続するように ActiveRecord が設定されます。この動作は、Rails 4.1 までにのみ必要です。それ以降のすべてのバージョンには、database.yml
で接続 URL と設定を指定するための直接サポートが含まれているため、それを上書きする必要はありません。
Rails アプリで PostgreSQL をローカルで使用するには、database.yml
に次の設定が含まれている必要があります。
development:
adapter: postgresql
host: localhost
username: user
database: app-dev
JRuby での接続
JRuby アプリケーションで PostgreSQL をデータベースとして使用するには、Gemfile
に activerecord-jdbcpostgresql-adapter
gem を含める必要があります。
gem 'activerecord-jdbcpostgresql-adapter'
bundle install
を実行して、すべての依存関係をダウンロードして解決します。
Rails を使用する場合、「Connecting with Rails」(Rails を使用した接続) の手順に従います。
Python での接続
Python アプリケーションで PostgreSQL をデータベースとして使用するには、psycopg2
パッケージを使用する必要があります。
$ pip install psycopg2-binary
また、コードでこのパッケージを使用して DATABASE_URL
に接続します。
import os
import psycopg2
DATABASE_URL = os.environ['DATABASE_URL']
conn = psycopg2.connect(DATABASE_URL, sslmode='require')
Django を使用した接続
pip
を使用して dj-database-url
パッケージをインストールします。
$ pip install dj-database-url
必ず、psycopg2-binary
および dj-database-url
を requirements.txt
ファイルにも追加してください。
DATABASE_URL
環境変数の値を解析し、それを Django が理解できる内容に変換するには、settings.py
の最後に次の行を追加します。
import dj_database_url
DATABASES['default'] = dj_database_url.config(conn_max_age=600, ssl_require=True)
Go での接続
pq を指定することにより、Go アプリを Heroku-Postgres に接続できます。 選択したクエリインターフェース (標準のデータベース/SQL) など) への Postgres データベースドライバー。 アプリは、ドライバーを直接使用するのではなく、クエリインターフェースを使用します。
標準の使用法 (データベース/SQL)
$ cd <app>
$ dep ensure -add github.com/lib/pq
import (
"database/sql"
_ "github.com/lib/pq"
)
...
func main() {
db, err := sql.Open("postgres", os.Getenv("DATABASE_URL"))
if err != nil {
log.Fatal(err)
}
...
}
SSL は、Heroku-Postgres に接続するために必要です。 pq は自動的に sslmode=require を設定します。 ただし、別のライブラリを使用する場合は、SSL を明示的に設定する必要があります。
標準ライブラリ以外
Postgres のより下位のアクセス許可では、pgx を使用できます。
データベース/SQL の時間節約の拡張機能の場合、sqlx を使用できます。
PHP での接続
一般的な考慮事項
フレームワークまたはライブラリで、URL としてフォーマットされたデータベース接続文字列をネイティブに処理できない場合、parse_url()
関数を使用して、DATABASE_URL
環境変数を解析してユーザー、パス、ホスト、ポート、データベース名の個別値を取り出します。
データベース名を表すため、先頭のスラッシュはパスコンポーネントからトリミングする必要があります。
$db = parse_url(getenv("DATABASE_URL"));
$db["path"] = ltrim($db["path"], "/");
結果として得られる $db
内の連想配列には、こちらに記載されているように、"path
"キーで入手可能なデータベース名を含む URL からの情報が含まれています。
PDO を使用した接続
DSN は、PDO を使用して接続するように構成する必要があります。
$db = parse_url(getenv("DATABASE_URL"));
$pdo = new PDO("pgsql:" . sprintf(
"host=%s;port=%s;user=%s;password=%s;dbname=%s",
$db["host"],
$db["port"],
$db["user"],
$db["pass"],
ltrim($db["path"], "/")
));
PGSQL 拡張機能を使用した接続
PQSQL 拡張機能は、URL スタイルの接続文字列をサポートする、基盤の libpq
ライブラリに接続文字列を直接渡します。したがって、DATABASE_URL
環境変数を直接使用できます。
$conn = pg_connect(getenv("DATABASE_URL"));
pq 拡張機能を使用した接続
pq 拡張機能は、URL スタイルの接続文字列をサポートする、基盤の libpq
ライブラリに接続文字列を直接渡します。したがって、DATABASE_URL
環境変数を直接使用できます。
$conn = new pq\Connection(getenv("DATABASE_URL"));
Laravel を使用した接続
config/database.php
ファイルは、データベース接続情報の配列をフレームワークに返します。これは単純に、最初に DATABASE_URL
環境変数で parse_url()
を呼び出し、抽出されたデータを返すように修正できます。
$DATABASE_URL = parse_url(getenv("DATABASE_URL"));
return [
// …
'connections' => [
// …
'pgsql' => [
'driver' => 'pgsql',
'host' => $DATABASE_URL["host"],
'port' => $DATABASE_URL["port"],
'database' => ltrim($DATABASE_URL["path"], "/"),
'username' => $DATABASE_URL["user"],
'password' => $DATABASE_URL["pass"],
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
'sslmode' => 'require',
],
// …
],
// …
];
Symfony 3 を使用した接続
DATABASE_URL
環境変数は、config.yml
で参照できます。Symfony の DoctrineBundle は、URL の内容を自動的に解析します。
Symfony 4 を使用した接続
Symfony 4 は、それ以上の設定なしで、DATABASE_URL
環境変数を自動的に選択します。
Node.js での接続
依存関係として pg
NPM モジュールをインストールします。
$ npm install pg
次に、process.env.DATABASE_URL
に接続します。
const { Client } = require('pg');
const client = new Client({
connectionString: process.env.DATABASE_URL,
ssl: {
rejectUnauthorized: false
}
});
client.connect();
client.query('SELECT table_schema,table_name FROM information_schema.tables;', (err, res) => {
if (err) throw err;
for (let row of res.rows) {
console.log(JSON.stringify(row));
}
client.end();
});
あるいは、PGSSLMODE
環境設定 heroku config:set PGSSLMODE=no-verify
を指定する場合は、ssl
設定オブジェクトを省略することもできます。