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
Copy いったんはここまでで大丈夫です。
ここからは単なるテストです。
この情報を使って 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.
Copy 接続できたようです。
データも参照できるかやってみます。
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 | 0055 h000003CqwWAAS | 2021 - 07 - 25 08 : 52 : 10 | | 0055 h000003CqwWAAS | PRODUCT_TEST_0000 | テストです | 2021 - 07 - 25 08 : 53 : 39 | 01 t5h000000AzOHAA0 | 20 | SYNCED |
( 1 row )
Copy 前回と同じデータが取れました。
スキーマ情報のダンプ pg_dump
を使ってスキーマ情報をダンプします。
1
$ pg_dump -d <データベース名> -h <ホスト名> -U <ユーザ名> --schema-only -t 'salesforce.*' -W > dump.sql
Copy この中にある 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 );
Copy これを 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
Copy 起動時SQLの準備 salesforce
スキーマをつくる 1.sql
というSQLを用意します。
1
CREATE SCHEMA salesforce ;
Copy この他、上で作った 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 |
...
Copy 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)
Copy 無事、salesforce.product2
スキーマが作成されていました。
まとめ Heroku PostgreSQLは heroku pg:credentials:url
で接続情報を取得できる Heroku Connectでつながった先のSalesforceのスキーマは pg_dump で取得する 取得したスキーマを使ってローカル環境にスキーマを再現することができる