DEV Community

Weerasak Chongnguluam
Weerasak Chongnguluam

Posted on

Run migrate Database schema ด้วย Go Migrate

Go migrate เป็นโปรแกรมช่วยเราจัดการการเปลี่ยนแปลงของ Datbase schema และจัดการ versioning ทำให้เราสามารถเปลี่ยนหรือย้อนกลับจากสิ่งที่เปลี่ยนไปแล้วกลับมาเหมือนเดิมได้ง่ายขึ้น

GitHub logo golang-migrate / migrate

Database migrations. CLI and Golang library.

GitHub Workflow Status (branch) GoDoc Coverage Status packagecloud.io Docker Pulls Supported Go Versions GitHub Release Go Report Card

migrate

Database migrations written in Go. Use as CLI or import as library.

  • Migrate reads migrations from sources and applies them in correct order to a database.
  • Drivers are "dumb", migrate glues everything together and makes sure the logic is bulletproof (Keeps the drivers lightweight, too.)
  • Database drivers don't assume things or try to correct user input. When in doubt, fail.

Forked from mattes/migrate

Databases

Database drivers run migrations. Add a new database?

Database URLs

Database connection strings are specified via URLs. The URL format is driver dependent but generally has the form: dbdriver://username:password@host:port/dbname?param1=true&param2=false

Any reserved URL characters need to be escaped. Note, the %

ตัว Go migrate เขียนด้วย Go นอกจากจะทำเป็นโปรแกรม CLI ให้เราเรียกใช้แล้ว ยังมีเป็น package library ให้เราเอาไปเรียกใช้ผ่าน Go ที่เราเขียนเองได้อีกด้วย

ตัวอย่างการใช้งานเช่นผมมี database ชื่อ example ซึ่งผมใช้ผ่าน PostgreSQL ผมต้องการสร้าง migration script สำหรับสร้าง table ชื่อ users ผมสามารถสั่งคำสั่ง migrate ได้ดังนี้

migrate create -ext sql -dir db/migrations -seq create_users_table
Enter fullscreen mode Exit fullscreen mode

ส่วน option ที่ส่งไปให้กับ migrate create ได้แค่ -ext sql คือบอกว่าให้นามสกุลของไฟล์ที่สร้างเป็น sql แล้วก็ -dir db/migrations คือให้สร้างไฟล์ที่ directory db/migrations แล้วก็ -seq บอกว่าให้สร้าง prefix ของไฟล์เป็น running number เป็นตัวเลขเรียงตามลำดับ เริ่มจาก 1 และสุดท้าย create_user_table เป็นชื่อไฟล์หลังจาก prefix ของตัวเลขด้านหน้า

หลังจากสั่งคำสั่งนี้ไปแล้วเราจะเห็นไฟล์ 2 ไฟล์ใน db/migrations ได้แก่

  • 000001_create_users_table.up.sql
  • 000001_create_users_table.down.sql

ซึ่งไฟล์ up ก็เอาไว้เขียน script ตอนที่เราสั่งให้ migrate มา version นี้ส่วน down ก็คือ script ตอนที่เราสั่งให้ถอยกลับคือเอา version นี้ออก

ตัวอย่างของไฟล์​ 000001_create_users_table.up.sql เช่น

CREATE TABLE IF NOT EXISTS users(
    user_id serial PRIMARY KEY,
    username CHARACTER VARYING UNIQUE NOT NULL,
    password CHARACTER VARYING NOT NULL,
    email CHARACTER VARYING UNIQUE NOT NULL
);
Enter fullscreen mode Exit fullscreen mode

ตัวอย่างของไฟล์ 000001_create_users_table.down.sql

DROP TABLE IF EXISTS users;
Enter fullscreen mode Exit fullscreen mode

หลังจากนั่นเมื่อเราต้องการให้รัน script up ของ version 1 เพื่อสร้าง table users เราก็สั่งผ่าน migrate command แบบนี้

migrate -database 'postgres://username:password@localhost:5432/example?sslmode=disable' -path db/migrations up
Enter fullscreen mode Exit fullscreen mode

โดยที่ -database 'postgres://username:password@localhost:5432/example?sslmode=disable' คือให้เราใส่ url connection ของ PostgreSQL ถ้าเป็นโปรแกรมฐานข้อมูลอื่นๆก็ใส่ url connection ต่างกันไปต้องไปดูคู่มือของ driver แต่ละแบบเองอีกที

ส่วน -path db/migrations ก็ใส่ path ของ script SQL ที่เราเขียน

ส่วนท้ายคือ up เพื่อสั่งให้ script up ทำงาน

หลังจากนั้นถ้าเราลิสต์ table ออกมาดูจะเห็นแบบนี้

               List of relations
 Schema |       Name        | Type  |  Owner   
--------+-------------------+-------+----------
 public | schema_migrations | table | weerasak
 public | users             | table | weerasak
(2 rows)
Enter fullscreen mode Exit fullscreen mode

จะเห็นว่ามี 2 tables สร้างขึ้นมา ลองดูเฉพาะ schema ของ users จะเป็น

                                     Table "public.users"
  Column  |       Type        | Collation | Nullable |                Default                 
----------+-------------------+-----------+----------+----------------------------------------
 user_id  | integer           |           | not null | nextval('users_user_id_seq'::regclass)
 username | character varying |           | not null | 
 password | character varying |           | not null | 
 email    | character varying |           | not null | 
Indexes:
    "users_pkey" PRIMARY KEY, btree (user_id)
    "users_email_key" UNIQUE CONSTRAINT, btree (email)
    "users_username_key" UNIQUE CONSTRAINT, btree (username)
Enter fullscreen mode Exit fullscreen mode

ส่วน schema_migrations ถ้าเราลอง select * from schema_migrations ดูจะพบข้อมูลแบบนี้อยู่

 version | dirty 
---------+-------
       1 | f
Enter fullscreen mode Exit fullscreen mode

ซึ่ง table นี้เป็น table ที่ Go migrate สร้างขึ้นมาเพื่อ track version ของ schema ถ้าเราสร้าง script เพิ่มเราก็จะได้ script ที่มี 2_ ข้างหน้าแล้วพอเราสั่ง up อีกรอบ script ของ version 2 ก็จะถูก run และ เลข version ในนี้ก็จะเปลี่ยนเป็น 2

ถ้าเราต้องการลบสิ่งที่เปลี่ยนแปลงไปจาก version ล่าสุดที่เราเพิ่งสั่ง up ก็ให้เราสั่ง down ได้ดังนี้

migrate -database 'postgres://username:password@localhost:5432/example?sslmode=disable'` -path db/migrations down 1
Enter fullscreen mode Exit fullscreen mode

แต่ถ้าต้องการ ถอยกลับที่หมดที่ up มาก็เอาเลข 1 ออก สั่งแค่ down แบบนี้

migrate -database 'postgres://username:password@localhost:5432/example?sslmode=disable'` -path db/migrations down
Enter fullscreen mode Exit fullscreen mode

นอกจากพื้นฐานตรงนี้แล้วก็ยังมี sub command อื่นๆอีก ลองสั่ง migrate -help ดูได้เลย

Top comments (0)