2020/05,江端さんの技術メモ

C:\Users\ebata>docker pull postgres:12.2
12.2: Pulling from library/postgres
bc51dd8edc1b: Pull complete
d2b355dbb6c6: Pull complete
d237363a1a91: Pull complete
ff4b9d2fde66: Pull complete
646492d166e7: Pull complete
828b1f103a3a: Pull complete
2ab9e3c9583f: Pull complete
4ab234e8a047: Pull complete
71b084e0c62f: Pull complete
bf30bd092a82: Pull complete
2aa61e9feb4e: Pull complete
aa5eca126d57: Pull complete
7046b64d69a3: Pull complete
a851dbb990ce: Pull complete
Digest: sha256:c5423e0febf82c33b5dc69aacd70d64418144db7bd355fa4ca30e6e5430b4123
Status: Downloaded newer image for postgres:12.2
docker.io/library/postgres:12.2

C:\Users\ebata>docker run -d --name postgres122 -e POSTGRES_PASSWORD=test -p 5432:5432 postgres:12.2
839317f0bb705daf5eac55cc6b4f74e0cbc49ff2f64e1efc9dd5e4d3f03e6515

C:\Users\ebata>docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
839317f0bb70 postgres:12.2 "docker-entrypoint.s…" 17 seconds ago Up 14 seconds 0.0.0.0:5432->5432/tcp postgres122

C:\Users\ebata>docker exec -ti postgres122 bash

2.準備
Windows10 BOX のC:\直下に、routing-20200221.sql を置いておく

3.ファイルのコピー
C:\Users\ebata>docker cp c:\routing-20200221.sql postgres122:/tmp/
でDockerの内部にコピー

4.コンテナに入る
C:\Users\ebata>docker exec -i -t postgres122 /bin/bash

5.コピーされているかを確認する
root@839317f0bb70:/# cd tmp
root@839317f0bb70:/tmp# ls
で、
routing-20200221.sql
が表示されたので成功

6.ローカルにdocker-compose.ymlを作成する

version: '3.7'

services:
  db:
    image: pgrouting/pgrouting:v3.0.0-dev-postgresql_12
    expose:
      - 5432
    ports:
    - 15432:5432
    volumes:
      - db_data
      - ./shared:/shared
  db_data:
    image: busybox
    volumes:
      - /data/db

8.次のコマンドを実施する
C:\Users\ebata>docker-compose up -d


9.DBの作成
C:\Users\ebata>docker-compose exec db createdb -h db -U postgres routing


10.postgisのインストール
C:\Users\ebata>docker-compose exec db psql -h db -U postgres -d routing -c 'CREATE EXTENSION pgrouting CASCADE; CREATE EXTENSION hstore;'


11.ダンプしたsqlの取り込み
C:\Users\ebata>docker-compose exec db psql -h db -U postgres routing -f /shared/routing-20200221.sql

2020/05,江端さんの技術メモ

can’t find package “github.com/lib/pq”

と、

Dockerで作ったpostgreSQLへの外部クライアントからのアクセス方法

を実施して、GoのプログラムからPostgreSQLサーバ(Docker版)にアクセスすることができました。

/*
go build -gcflags "-N -l" main.go

uft-8でセーブ

まず、以下の手順でテーブルを作っておく
 
C:\Users\yrl-user>psql -h localhost -U postgres	

postgres=# create database blogapp;

postgres=# \l		
postgres=# \connect blogapp(データベース名)
 
以下をコピペしてテーブルとその内容を直接書き込む
 
create table users (
	   id serial primary key,
	   name varchar(255),
	   score real,
	   team varchar(255)
					);
 
insert into users (name, score, team) values
('taguchi', 5.5, 'red'),
('fkoji', 8.3, 'blue'),
('dotinstall', 2.2, 'blue'),
('sakaki', 5.0, 'green'),
('sasaki', 4.6, 'red'),
('kimura', 4.7, 'green');
 
blogapp=# \dt
blogapp=# \d users(テーブル名)
 
データベースのテーブルの中身を確認する
blogapp=# select * from users; // 検索の基本形
 
*/



package main

import (
    "fmt"
    "database/sql"
    _ "github.com/lib/pq"
    "os"
)

// ----------------------------------------------------------------

func checkError(err error) {
	if err != nil {
		fmt.Fprintf(os.Stderr, "fatal: error: %s", err.Error())
		os.Exit(1)
	}
}

func main() {
    fmt.Fprintln (os.Stderr,"*** start ***")

	db, err := sql.Open("postgres", "user=postgres dbname=blogapp password=c-anemone sslmode=disable")

	checkError(err)
    defer db.Close()

	sql_str := "select id,name,score,team from users order by id"

    rows, err := db.Query(sql_str)
    if err != nil {
        fmt.Println(err)
        }

    defer rows.Close()

    for rows.Next() {
        var id string
        var name string 
        var score float32
        var team string 
        if err := rows.Scan(&id,&name,&score,&team); err != nil {
            fmt.Println(err)
        }
        fmt.Printf ("%s\t%s\t%f\t%s\n",id, name,score,team)
    }

    if err := rows.Err(); err != nil {
        fmt.Println(err)
        }

    fmt.Fprintln (os.Stderr,"*** end ***")
}

出力結果

*** start ***
1	taguchi	5.500000	red
2	fkoji	8.300000	blue
3	dotinstall	2.200000	blue
4	sakaki	5.000000	green
5	sasaki	4.600000	red
6	kimura	4.700000	green
*** end ***

ようやく一安心できました。

2020/05,江端さんの技術メモ

「DockerのpostgreSQLの起動方法」で、postgreSQL(ポスグレ)サーバは作れたのは良かったのですが、クライアント(例 pgAdmin4)からアクセスできないことが分かりました。どうやら原因は、パスワードがない、ということのようです。fe_sendauth: no password suppliedが消えません。

私は、CとかGoのプログラムから、ポスグレを使おうとしていますが、pgAdmin4からアクセスできないとなると、多分、「CとかGoのプログラムからは動せない」と思いました。

ロールやらなんやらを追加する方法もあるようですが、私は、ポスグレの運用は、できるだけ手を抜きたいし、そもそもポスグレを外部公開する予定はないので、セキュリティもスカスカでかまいません(もちろん、SSHなんぞも不要)。

そこで、Dockerのポスグレにパスワード("c-anemone")を追加しました。

C:\Users\ebata>docker start -a postgres122

C:\Users\ebata>docker container exec -it postgres122 bash

root@19e323b3f7c1:/# psql -U postgres

とした状態で、

postgres=# alter role postgres with password 'c-anemone';

と打ち込んだ後、psqlからログアウトして、別のコンソールから、

C:\Users\ebata>docker stop postgres122

C:\Users\ebata>docker start -a postgres122

と再起動をしました。

その後、pgAdmin4のCreateの設定画面にパスワードを入力したら、

さくっとログインできました。

2020/05,江端さんの技術メモ

よく忘れるのでメモしておく。

C:\Users\ebata>docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
19e323b3f7c1 postgres:12.2 "docker-entrypoint.s…" 2 months ago Exited (255) 2 months ago 0.0.0.0:5432->5432/tcp postgres122
70fa5aa3a11d pgrouting/pgrouting:v3.0.0-dev-postgresql_12 "docker-entrypoint.s…" 2 months ago Exited (255) 2 months ago 0.0.0.0:15432->5432/tcp ebata_db_1
78c979ee1238 busybox "sh" 2 months ago Exited (0) 2 months ago ebata_db_data_1
C:\Users\ebata>docker start -a postgres122
PostgreSQL Database directory appears to contain a database; Skipping initialization
2020-05-24 15:58:13.237 UTC [1] LOG: starting PostgreSQL 12.2 (Debian 12.2-2.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
2020-05-24 15:58:13.250 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
2020-05-24 15:58:13.250 UTC [1] LOG: listening on IPv6 address "::", port 5432
2020-05-24 15:58:13.290 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2020-05-24 15:58:13.352 UTC [24] LOG: database system was interrupted; last known up at 2020-03-12 10:28:44 UTC
2020-05-24 15:58:13.535 UTC [24] LOG: database system was not properly shut down; automatic recovery in progress
2020-05-24 15:58:13.568 UTC [24] LOG: redo starts at 0/166F4D8
2020-05-24 15:58:13.569 UTC [24] LOG: invalid record length at 0/166F5C0: wanted 24, got 0
2020-05-24 15:58:13.569 UTC [24] LOG: redo done at 0/166F588
2020-05-24 15:58:13.730 UTC [1] LOG: database system is ready to accept connections
C:\Users\ebata>docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
19e323b3f7c1 postgres:12.2 "docker-entrypoint.s…" 2 months ago Up 13 minutes 0.0.0.0:5432->5432/tcp postgres122
C:\Users\ebata>docker container exec -it postgres122 bash
root@19e323b3f7c1:/# ls
bin boot dev docker-entrypoint-initdb.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@19e323b3f7c1:/# psql -U postgres
psql (12.2 (Debian 12.2-2.pgdg100+1))
Type "help" for help.
postgres-# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+------------+------------+-----------------------
ca_db | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)
postgres-# \c ca_db
You are now connected to database "ca_db" as user "postgres".

その他、viを使いたければ、

root@19e323b3f7c1:/#apt-get update

root@19e323b3f7c1:/#apt-get install vim

2020/05,江端さんの技術メモ

下記のプログラムをコンパイルする

/*
		go build -gcflags "-N -l" main.go
*/
package main

import (
    "fmt"
    "database/sql"
    _ "github.com/lib/pq"
    "os"
)

// ----------------------------------------------------------------
func main() {
    fmt.Fprintln (os.Stderr,"*** 開始 ***")
    db, err := sql.Open("postgres", "user=scott dbname=city password=tiger123 sslmode=disable")
    defer db.Close()

    sql_str := "select id,name,population,date_mod from cities order by id"

    rows, err := db.Query(sql_str)
    if err != nil {
        fmt.Println(err)
        }
    defer rows.Close()

    for rows.Next() {
        var id string
        var name string 
        var population int
        var date_mod string 
        if err := rows.Scan(&id,&name,&population,&date_mod); err != nil {
            fmt.Println(err)
        }
        fmt.Printf ("%s\t%s\t%d\t%s\n",id, name,population,date_mod)
    }

    if err := rows.Err(); err != nil {
        fmt.Println(err)
        }

    fmt.Fprintln (os.Stderr,"*** 終了 ***")
}

で "github.com/lib/pq" がない、とエラーが出てくる。

C:\Users\ebata>go get github.com/lib/pq

で、すんなりインストール成功。で、コンパイルをしたら通ったので、とりあえずメモしておく。これからdockerでDBつくって動作を試す。

2020/05,江端さんの技術メモ

package main

import (
	"fmt"
	"strings"
)

func main() {
	c0 := make(chan string)  // makeってなんだ? →"配列"でも"共有メモリ"でもいいが、
	c1 := make(chan string)  // 江端理解では「トンネル」とか「パイプ」とか「Amazonのダンボール箱」 

	go sourceGopher(c0)      // "c0"とラベルの付いたダンボール箱を使うぜ
	go filterGopher(c0, c1)  // "c0","c1"とラベルの付いたダンボール箱を使うぜ 
	printGopher(c1)          // "c1"とラベルの付いたダンボール箱を使うぜ
}

func sourceGopher(downstream chan string) {
	for _, v := range []string{"hello world", "a bad apple", "goodbye all"} {
		downstream <- v   // "c0"のダンボール箱に、(1)"hello world",(2)"a bad apple", (3)"goodbye all"を投げ入れる
	}
	downstream <- ""   // "c0"のダンボール箱の底にクッション(プチプチ)を入れる
}

func filterGopher(upstream, downstream chan string) {
	for {
		item := <-upstream     // "c0"のダンボール箱からクッションを取り出す
		if item == "" {        // クッションだったら
			downstream <- ""   // "c1"のダンボール箱にクッションを入れる
			return             // ダンボール箱の蓋を閉める
		}
		if !strings.Contains(item, "bad") {   // "bad"という文字列が入っていない荷物だったら
			downstream <- item // "c1"のダンボール箱に荷物を入れる
		}
	}
}
func printGopher(upstream chan string) {
	for {
		v := <-upstream // "c1"のダンボール箱から荷物を出す
		if v == "" {    // "c1"の荷物がクッションだったら
			 return     // ダンボール箱を閉める
		}
		fmt.Println(v)  // 荷物を読み上げる
	}
}

2020/05,江端さんの技術メモ

良く忘れるので書いておく。

(1)Goは一度も使われない変数があると、全部エラーにしてしまう → 「せっかく買ったのに、どうして使わないの?」と言い続ける、うっとうしい母親みたいなもの

(2)返り値のある変数があるけど、別に返り値が必要でないときがある。
例えば、2つの返り値がある関数で、「2つもはいらんわ」という時に、こうなる

f := func(num1 int, num2 int)(int, int){
	return num1 + num2, num1 - num2
}
ret1, ret2 := f(8, 7)  // "a"が不使用のためエラー:a declared and not used
fmt.Println(ret2)

(3)でも、こうすれば、エラーにならない

ret1 はいらん → これを"_"と書く

_, ret2 := f(8, 7)  // エラーがでてこなくなる
fmt.Println(ret2)

2020/05,江端さんの技術メモ

// go build -gcflags "-N -l" main.go ← これで、golangのプログラムをgdbで動かすことができたぞ(マグレかもしれないけど)

package main

import (
    "fmt"
    "time"
)

func counting(c chan<- int) {
    for i := 0; i < 10; i++ {
        time.Sleep(2 * time.Second)
        c <- i
    }
    close(c)
}

func main() {
    msg := "Starting main"
    fmt.Println(msg)
    bus := make(chan int)
    msg = "starting a gofunc"
    go counting(bus)

    for count := range bus {
        fmt.Println("count:", count)
    }
}

2020/05,江端さんの技術メモ

PostgresSQLは使い慣れてくると手放せなくなります。もう、テーブルをプログラムの中に作るな面倒くさくてやっていられません。どんなに小さいテーブルでも、PostgreSQLにつくって、そのまま放置しておきます。CSVすら面倒くさい。

しかし、PostgreSQLは頻繁にバージョンアップするので、結構面倒くさい思いをします。

そこで、Dockerで作って、そのまま放置するという戦略を取ることにしました。理屈は分からないけど、取り敢えず、ネットの情報を使ってここまでやってみたところ、動いているっぽいです。

C:\Users\ebata> docker run --rm -d -p 15432:5432 -v postgres-tmp:/var/lib/postgresql/data -e POSTGRES_HOST_AUTH_METHOD=trust postgres:12-alpine

C:\Users\ebata>docker container ls

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e373f69553b8 postgres:12-alpine "docker-entrypoint.s…" 11 minutes ago Up 11 minutes 0.0.0.0:15432->5432/tcp frosty_golick

C:\Users\ebata>docker container exec -it frosty_golick bash

bash-5.0# psql -U postgres
psql (12.3)
Type "help" for help.

postgres=#