tamuです。
Heroku Connectを使った際のローカルでの開発について調査しました。
常にHerokuにデプロイして動作確認をするのは実行コストがかかるので、
ローカルのPostgreSQLにHeroku Connect同等のスキーマを用意する手順をまとめました。
Heroku Connect の接続
前回記事を参考に、Heroku Connectを使ってSalesforceのレコードをPostgreSQLで参照できるようにします。
Salesforceスキーマのダンプ
pg_dump
を使い、Salesforceスキーマをダンプします。
その前にHeroku PostgreSQLへの接続情報を取得します。
Heroku PostgreSQLの接続情報の取得
heroku pg:credentials:url
でHeroku PostgreSQLへの接続情報を取得することができます。
1
2
3
4
5
6
| $ heroku pg:credentials:url -a <app-name>
Connection information for default credential.
Connection info string:
"dbname=xxxxxxxxxxxxxx host=ec2-xx-xx-xx-xx.xxxxxxxxxx.amazonaws.com port=xxxx user=xxxxxxxxxxxxxx password=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx sslmode=require"
Connection URL:
postgres://xxxxxxxxxxxxxx:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@ec2-xx-xx-xx-xx.xxxxxxxxxx.amazonaws.com:xxxx/xxxxxxxxxxxxxx
|
いったんはここまでで大丈夫です。
ここからは単なるテストです。
この情報を使って psql
で接続できるかやってみます。
1
2
3
4
5
| psql -U <ユーザ名> -h <ホスト名> -p <ポート番号> -W <データベース名>
Password:
psql (13.3, server 13.4 (Ubuntu 13.4-1.pgdg20.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.
|
接続できたようです。
データも参照できるかやってみます。
1
2
3
4
5
| xxxxxxxxxxx=> select * from salesforce.product2;
externalproductid__c | family | externalid | lastvieweddate | stockkeepingunit | name | externaldatasourceid | displayurl | lastmodifieddate | isdeleted | isactive | systemmodstamp | lastmodifiedbyid | createddate | quantityunitofmeasure | createdbyid | productcode | description | lastreferenceddate | sfid | id | _hc_lastop | _hc_err
----------------------+--------+------------+---------------------+------------------+-----------------------------------+----------------------+------------+---------------------+-----------+----------+---------------------+--------------------+---------------------+-----------------------+--------------------+-------------------+-------------+---------------------+--------------------+----+------------+---------
PRODUCT_TEST_0000 | | | 2021-07-25 08:53:39 | | テスト | | | 2021-07-25 08:52:10 | f | f | 2021-07-25 08:52:10 | 0055h000003CqwWAAS | 2021-07-25 08:52:10 | | 0055h000003CqwWAAS | PRODUCT_TEST_0000 | テストです | 2021-07-25 08:53:39 | 01t5h000000AzOHAA0 | 20 | SYNCED |
(1 row)
|
前回と同じデータが取れました。
スキーマ情報のダンプ
pg_dump
を使ってスキーマ情報をダンプします。
1
| $ pg_dump -d <データベース名> -h <ホスト名> -U <ユーザ名> --schema-only -t 'salesforce.*' -W > dump.sql
|
この中にある salesforce.product2
に関連するSQLを抽出してきます。
(トリガ処理は除外しています)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
| CREATE TABLE salesforce.product2 (
externalproductid__c character varying(255),
family character varying(255),
externalid character varying(255),
lastvieweddate timestamp without time zone,
stockkeepingunit character varying(180),
name character varying(255),
externaldatasourceid character varying(18),
displayurl character varying(1000),
lastmodifieddate timestamp without time zone,
isdeleted boolean,
isactive boolean,
systemmodstamp timestamp without time zone,
lastmodifiedbyid character varying(18),
createddate timestamp without time zone,
quantityunitofmeasure character varying(255),
createdbyid character varying(18),
productcode character varying(255),
description character varying(4000),
lastreferenceddate timestamp without time zone,
sfid character varying(18) COLLATE pg_catalog.ucs_basic,
id integer NOT NULL,
_hc_lastop character varying(32),
_hc_err text
);
CREATE SEQUENCE salesforce.product2_id_seq
AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE salesforce.product2_id_seq OWNED BY salesforce.product2.id;
ALTER TABLE ONLY salesforce.product2 ALTER COLUMN id SET DEFAULT nextval('salesforce.product2_id_seq'::regclass);
ALTER TABLE ONLY salesforce.product2
ADD CONSTRAINT product2_pkey PRIMARY KEY (id);
CREATE INDEX hc_idx_product2_lastmodifieddate ON salesforce.product2 USING btree (lastmodifieddate);
CREATE INDEX hc_idx_product2_systemmodstamp ON salesforce.product2 USING btree (systemmodstamp);
CREATE UNIQUE INDEX hcu_idx_product2_externalproductid__c ON salesforce.product2 USING btree (externalproductid__c);
CREATE UNIQUE INDEX hcu_idx_product2_sfid ON salesforce.product2 USING btree (sfid);
|
これを 2.sql
のような名前をつけて保存しておきます。
※ 1.sql
は後述
ローカル環境の準備
ローカルはdockerで環境を作ると色々と楽なのでdockerで準備していきます。
docker-compose.yml の作成
ポイントは herokuconnect
ディレクトリを用意して、起動時にその中にあるSQLファイルを実行できるようにしてある点です。
こうすることで、Heroku Connect先(Salesforce側)のスキーマを事前に定義することができます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| version: "3"
services:
dbserver:
image: postgres:12
container_name: herokuconndb
ports:
- 5432:5432
environment:
POSTGRES_USER: root
POSTGRES_PASSWORD: password
POSTGRES_DB: herokuconn
POSTGRES_INITDB_ARGS: "--encoding=UTF-8"
volumes:
- database:/var/lib/postgresql/data
- ./herokuconnect:/docker-entrypoint-initdb.d
volumes:
database:
driver: local
|
起動時SQLの準備
salesforce
スキーマをつくる 1.sql
というSQLを用意します。
1
| CREATE SCHEMA salesforce;
|
この他、上で作った 2.sql
を用意し、 herokuconnect
ディレクトリに放り込んでおきます。
ローカルのデータベースの起動
docker compose up
でPostgreSQLを起動します。
起動すると herokuconnect
ディレクトリにあるSQLファイルを順番に読み込み、実行してくれます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| ...
herokuconndb | server started
herokuconndb | CREATE DATABASE
herokuconndb |
herokuconndb |
herokuconndb | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/1.sql
herokuconndb | CREATE SCHEMA
herokuconndb |
herokuconndb |
herokuconndb | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/2.sql
herokuconndb | CREATE TABLE
herokuconndb | CREATE SEQUENCE
herokuconndb | ALTER SEQUENCE
herokuconndb | ALTER TABLE
herokuconndb | ALTER TABLE
herokuconndb | CREATE INDEX
herokuconndb | CREATE INDEX
herokuconndb | CREATE INDEX
herokuconndb | CREATE INDEX
herokuconndb |
...
|
psql
でつないでスキーマができているか確認してみます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| $ psql -U root -h 127.0.0.1 -W herokuconn
Password:
psql (13.3, server 12.8 (Debian 12.8-1.pgdg100+1))
Type "help" for help.
herokuconn=# \d salesforce.product2
Table "salesforce.product2"
Column | Type | Collation | Nullable | Default
-----------------------+-----------------------------+-----------+----------+-------------------------------------------------
externalproductid__c | character varying(255) | | |
family | character varying(255) | | |
externalid | character varying(255) | | |
lastvieweddate | timestamp without time zone | | |
stockkeepingunit | character varying(180) | | |
name | character varying(255) | | |
externaldatasourceid | character varying(18) | | |
displayurl | character varying(1000) | | |
lastmodifieddate | timestamp without time zone | | |
isdeleted | boolean | | |
isactive | boolean | | |
systemmodstamp | timestamp without time zone | | |
lastmodifiedbyid | character varying(18) | | |
createddate | timestamp without time zone | | |
quantityunitofmeasure | character varying(255) | | |
createdbyid | character varying(18) | | |
productcode | character varying(255) | | |
description | character varying(4000) | | |
lastreferenceddate | timestamp without time zone | | |
sfid | character varying(18) | ucs_basic | |
id | integer | | not null | nextval('salesforce.product2_id_seq'::regclass)
_hc_lastop | character varying(32) | | |
_hc_err | text | | |
Indexes:
"product2_pkey" PRIMARY KEY, btree (id)
"hc_idx_product2_lastmodifieddate" btree (lastmodifieddate)
"hc_idx_product2_systemmodstamp" btree (systemmodstamp)
"hcu_idx_product2_externalproductid__c" UNIQUE, btree (externalproductid__c)
"hcu_idx_product2_sfid" UNIQUE, btree (sfid)
|
無事、salesforce.product2
スキーマが作成されていました。
まとめ
- Heroku PostgreSQLは
heroku pg:credentials:url
で接続情報を取得できる - Heroku Connectでつながった先のSalesforceのスキーマは pg_dump で取得する
- 取得したスキーマを使ってローカル環境にスキーマを再現することができる