【譯】在幾秒鐘內爲你的開發環境建立一個私有 PostgreSQL 數據庫

在幾秒鐘內爲你的開發環境建立一個私有 PostgreSQL 數據庫

Photo by Roi Dimor on Unsplash

不少開發者在開始一個新項目的時候,一般會使用 JSON,CSV 或者其餘 Flat File 來模擬真實存放在數據庫中的數據。這是由於他們老是在沒有真實的數據庫環境限制和是否須要本身建立模擬數據庫之間左右爲難。既然這樣,爲何不使用 Docker Compose 定義一個能夠在幾秒鐘內建立、銷燬和從新建立的 PostgreSQL 數據庫和監視工具html

Image source: Author

正確建立配置兩個容器的 Docker 命令過於冗長。而使用 Docker Compose,你只須要記住 up 命令和 down 命令!前端

Up 命令將建立指定版本的 PostgreSQL 數據庫和一個 GUI 管理工具。Down 命令會將其關閉並刪除。android

基於私有容器的數據庫的好處

  • 不一樣版本的 PostgreSQL 在行爲和功能上存在差別,所以開發人員應針對一個數據庫版本進行長期開發。你能夠選擇的一個版本是 9.6.12,另外一個能夠是 12.4。
  • 大多數程序員都不是數據庫管理員或 SQL 專家。可視化工具可讓他們直觀地驗證其代碼的運行效果並支持手動修改數據。
  • 項目的不一樣階段須要不一樣類型的存儲方案。在項目早期,非持久型數據庫能夠最大程度地減小麻煩。在項目的後期階段,持久型數據庫提供了更實際的方案。

Create and recreate a database with simple commands

創建開發堆棧

下面所展現的這份 docker-compose.yml 文件定義了一個運行特定版本 PostgreSQL 和 pgAdmin 4(Postgres 最經常使用的管理工具)的 PostgreSQL 容器。該文件的內容值得咱們詳細的探討。ios

version: "3.8"
services:
  postgres:
    image: postgres:9.6.12-alpine
    container_name: some-postgres
    volumes:
      - "~/Documents/docker_pgsql_init:/docker-entrypoint-initdb.d"
      - "~/Documents/docker_pgsql_volume:/var/lib/postgresql/data"
    ports:
      - 5432:5432
    environment:
      - POSTGRES_PASSWORD=mysecret
    deploy:
      restart_policy:
        condition: on-failure
        max_attempts: 3

  pgadmin:
    image: dpage/pgadmin4
    container_name: some-pgadmin
    volumes:
      - ${PWD}/servers.json:/pgadmin4/servers.json
    ports:
      - 8080:80
    environment:
      - PGADMIN_DEFAULT_EMAIL=user@domain.com
      - PGADMIN_DEFAULT_PASSWORD=admin
    deploy:
      restart_policy:
        condition: on-failure
        max_attempts: 3
複製代碼

Docker Compose 的文件結構

該文件定義了兩個要建立的「服務」:Postgres 和 pgAdmin。每一個服務都包含一個從 Docker Hub 拉取的容器。Postgres 和 pgAdmin 將分別開放 5432 端口和 8080 端口。將你寫的任何程序指向主機名「localhost」,而後用瀏覽器訪問 http://localhost:8080 便可訪問 pgAdmin。git

繼續閱讀有關如何將 pgAdmin 指向 Postgres 的說明。程序員

PostgreSQL 的版本

在定義 Postgres 容器的這一行中,你須要準確指定所需的 Postgres 版本。在這裏,版本是一個標籤,而 9.6.12-alpine 就是示例中使用的版本。點擊這裏查看其餘可用的版本github

Postgres 的存儲

上面的 docker-compose.yml 文件爲 Postgres 指定了兩個 volume 映射。這兩個映射將使 Postgres 能夠訪問你計算機上的目錄。web

  1. 被映射到 /docker-entrypoint-initdb.d 的文件夾包含了初始化 Postgres 將會用到的 SQL 文件。將所需的 SQL 文件和 Shell 腳本放在該目錄中,它們將會按字母順序自動執行。
  2. 被映射到 /var/lib/postgresql/data 的文件夾存放了數據庫持久化存儲所須要的實際文件。

當 Postgres 啓動時,他的簡單運行流程以下圖所示。若是數據庫中沒有數據,那麼它將執行被映射到 /docker-entrypoint-initdb.d 目錄中的每一個 SQL 文件和 Shell 腳本(按字母順序)。若是被映射到 /var/lib/postgresql/data 目錄的文件夾中有數據,那麼它將會忽略掉這些文件。sql

你是否須要掛載這兩個目錄?這個得視狀況而定。下表描述了經過 Postgres 的兩個不一樣映射獲得的一個預期結果。docker

個人建議是對這兩個文件目錄都作映射。若是你不想再初始化你的數據庫,你能夠從 init 目錄中刪除文件。你也能夠在你的計算機上刪除任何可能已經持久化的數據(當你下一次運行 docker-compose up 命令時,Docker 將會在其位置從新建立一個空文件夾)。

專業提示:你能夠將 CSV 文件放在計算機的 init 文件夾中,而後在 init 目錄中經過適當的 SQL 命令將 CSV 文件中的數據填充到數據表中。

CREATE TABLE Employee(id, first_name, last_name, salary);
COPY Employee FROM '/docker-entrypoint-initdb.d/emp.csv'
    WITH (FORMAT CSV, HEADER);
複製代碼

pgAdmin 的存儲

儘管 pgAdmin 只是一個用於查看和配置數據庫的工具,但必須配置其與數據庫的鏈接。這能夠經過可視化工具中的 add server指令完成。這裏須要注意的是,主機名(the hostname)是咱們在 YML 文件中配置的 container_name 這一參數的名稱,即 some-postgres。一樣地,密碼也已經在 YML 文件中指定了,即 mysecret

另外一種方法是經過在 JSON 文件中指定這些配置(除了密碼以外的全部配置),經過這種方式能夠免去大量的單擊和輸入操做。爲了不手動配置 pgAdmin 到 Postgres 的鏈接,咱們須要將該 JSON 文件映射到容器 /pgadmin4/servers.json 上(在示例 YML 文件中的第 22 行)。

設置文件能夠指定 pgAdmin 和 Postgres 之間的多個鏈接(以不一樣用戶的身份鏈接或者鏈接到多個不一樣的數據庫)。下面是隻有一個數據庫鏈接的示例。

{
    "Servers": {
        "1": {
            "Name": "my-postgres",
            "Group": "Servers",
            "Port": 5432,
            "Username": "postgres",
            "Host": "some-postgres",
            "SSLMode": "prefer",
            "MaintenanceDB": "postgres"
        }
    }
}
複製代碼

網絡

container_name 參數僅僅只表示一個名字。可是 pgAdmin 將使用這個名稱訪問 5432 端口上的數據庫。緣由以下圖所示。這兩個容器經過私有網絡相互鏈接,所以能夠經過它們的主機名(容器名)也就是 some-postgressome-pgadmin 相互訪問。然而,你的主機(也就是你的計算機和 web 瀏覽器)只能訪問容器對外暴露的 5432 端口和 8080 端口,所以你能夠經過 localhost:5432localhost:8080 訪問它們。

內部網絡的名稱能夠在 compose 文件中指定,可是爲一個從未被代碼引用的網絡命名沒有任何價值!若是你仍是好奇,能夠隨時查看你的私人及臨時網絡的名稱。在下面的代碼片斷中,我從桌面運行了 Docker Compose,所以將該網絡命名爲 desktop_default

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
23a6be9b8021        bridge              bridge              local
49a120440f88        desktop_default     bridge              local
44a949b56fa7        host                host                local
3892b16dca2d        none                null                local
複製代碼

Docker 和 docker-compose 命令

在這裏,我必須認可我在前言中過於簡化了命令操做,但只是稍微簡化了一點。

爲了啓動容器,可使用 docker-compose up -d-d 參數指定這是一個 detached 模式,它將會在後臺運行,而且不會影響你在命令提示符中執行其餘命令。

$ docker-compose up -d
Creating network "desktop_default" with the default driver
Creating some-postgres ... done
Creating some-pgadmin  ... done
$
複製代碼

爲了關閉並刪除容器,你可使用 docker-compose down -v-v 參數表示刪除容器在運行時使用的 volume。這個不會刪除計算機映射到容器上的目錄。

$ docker-compose down -v
Stopping some-pgadmin  ... done
Stopping some-postgres ... done
Removing some-pgadmin  ... done
Removing some-postgres ... done
Removing network desktop_default
複製代碼

隨着時間的推移,若是不使用 -v 標誌,就會累積沒必要要的 volume。你可使用 docker volume ls 來驗證這一點。

若是要調試一個沒有正確啓動的容器,請使用 docker logs [container_name]。例如,因爲 init 目錄中的一個 SQL 文件中出現錯誤,數據庫可能沒法正確初始化。經過執行 docker logs some-postgres 命令,能夠生成容器啓動時記錄的日誌,經過對該日誌的查閱,我在一個特殊命名的 SQL 文件中發現一個錯誤:

/usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/broken.sql
ERROR:  syntax error at end of input at character 34
STATEMENT:  CREATE TABLE Songs(id, name, year
psql:/docker-entrypoint-initdb.d/broken.sql:1: ERROR:  syntax error at end of input
LINE 1: CREATE TABLE Song(id, name, year
複製代碼

日誌告訴我在 broken.sql 文件的第 1 行有一個錯誤。該命令缺乏右括號和分號。我能夠修復這個錯誤,並使用 downup 來驗證。


使用 Python

使用 localhost 做爲 YML 文件中指定的主機名和密碼,鏈接到數據庫很容易。

import psycopg2

# connect to DB
conn = psycopg2.connect(host="localhost", dbname="postgres", user="postgres",
    password="mysecret")
cursor = conn.cursor()

# execute SQL commands in SQL file
cursor.execute(open("emp.sql", "r").read())

# retrieve data from the database
cursor.execute("SELECT * FROM Employee")
print(cursor.fetchall())
複製代碼

使用 pgAdmin

簡單的訪問 http://localhost:8080 便可進入登陸界面,使用你在 docker-compose.yml 文件中定義的用戶名和密碼登陸便可(在咱們的示例中是 user@domain.comadmin)。

若是你使用的是本文以前討論的 servers.json 文件來指定鏈接細節,你將會在展開用戶界面左側的導航樹時,收到系統要求你輸入 Postgres 數據庫的密碼的提示。在咱們示例的 docker-compose.yml 文件中,這個密碼是 mysecret。若是你並無建立 servers.json 文件或文件中有錯誤,你就必須手動添加服務器。

如今,你應該可以查看和操做數據庫了。

進入 PSQL

有時候,開發者須要一個熟悉的命令行。Docker 使得訪問 PSQL 和執行高級用戶命令等操做變得更加容易。執行下面的命令進入 PSQL 命令行。

鏈接後,你就能夠執行全部 PSQL 命令,例如,輸入 \i 用於導入外部數據庫,輸入 \dt 顯示數據表的描述,輸入 \df 顯示函數的描述。想要退出,可使用 \q 命令。

$ docker exec -it some-postgres psql -U postgres

psql (9.6.12)
Type "help" for help.

postgres=# \dt
List of relations
Schema |     Name     | Type  |  Owner
--------+--------------+-------+----------
public | peak         | table | postgres
public | climb        | table | postgres
public | climber      | table | postgres
複製代碼

pgAdmin 的替代品

Adminer is a much simpler interface

pgAdmin 是 PostgreSQL 最多見的 GUI 管理工具,但咱們還有其餘選擇。Adminer 的使用更加簡單,而且你可能已經擁有使用它的經驗了,由於它支持多種風格的 SQL。若是你是剛開始使用 PostgreSQL 或者只有很是簡單的需求,那麼它多是一個更合適你的工具。

在登陸界面上,設置主機名爲 some-postgres ,密碼爲 mysecret

要在你的環境中用 Adminer 替換 pgAdmin,你須要在 docker-compose.yml 中替換幾行有關 pgAdmin 容器的定義。

adminer:
    image: adminer
    container_name: some-adminer
    ports:
      - 8080:8080
    deploy:
      restart_policy:
        condition: on-failure
        max_attempts: 3
複製代碼

參考資料

全部優秀的開發者都依賴於產品文檔和其餘人員的經驗。這是我在建立工做流程和編寫本文時引用的參考資料。

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索