آموزش استفاده از Go Migrate

1. مروری بر Go Migrate

Go Migrate ابزاری برای مدیریت مهاجرت پایگاه داده به زبان Go است. می‌توان آن را به عنوان یک رابط خط فرمان (CLI) استفاده کرد یا به عنوان یک کتابخانه برای پروژه‌های Go وارد کرد. Go Migrate می‌تواند فایل‌های مهاجرت را از منابع مختلف بخواند و آن‌ها را به ترتیب صحیح در پایگاه داده اعمال کند. این ابزار از درایورهای مختلف پایگاه داده و منابع مهاجرت پشتیبانی می‌کند.

2. نسخه‌ها

Go Migrate از نسخه‌های متعددی پشتیبانی می‌کند که شامل موارد زیر است:

  • Master: آخرین نسخه که شامل ویژگی‌ها و رفع باگ‌های جدید است
  • v4: نسخه پایدار، مناسب برای محیط‌های تولید
  • v3: دیگر پشتیبانی نمی‌شود و نباید استفاده شود

3. نصب

برای استفاده از Go Migrate، باید پکیج Go را نصب کنید. دستور زیر را برای نصب اجرا کنید:

go get -u -d github.com/golang-migrate/migrate/v4
cd $GOPATH/src/github.com/golang-migrate/migrate/v4

3. استفاده از Go Migrate

Go Migrate می‌تواند از طریق خط فرمان یا به عنوان یک کتابخانه در پروژه Go استفاده شود.

3.0. URL‌های اتصال پایگاه داده

به طور مستقل از استفاده از خط فرمان یا کد Go، URL‌های پایگاه داده برای اتصال به پایگاه داده باید پیکربندی شود.

فرمت URL:

dbdriver://username:password@host:port/dbname?param1=true&param2=false

این URL یک URL اتصال پایگاه داده است که برای اتصال به پایگاه داده و تعیین پارامترهای اتصال استفاده می‌شود. اینجا توضیحات هر قسمت درج شده است:

  1. dbdriver://: این شناسه پروتکل برای درایور پایگاه داده استفاده می‌شود تا درایور مورد استفاده برای پایگاه داده (مانند mysql) مشخص شود.
  2. username:password: این نام کاربری و رمز عبور برای احراز هویت استفاده می‌شود. به طور معمول، نام کاربری و رمز عبور توسط دونقطه (:) از یکدیگر جدا می‌شوند.
  3. @: این نماد برای جدا کردن نام کاربری و رمز عبور از نام میزبان و پورت استفاده می‌شود.
  4. host:port: این نام میزبان و شماره پورت سرور پایگاه داده است. نام میزبان آدرس IP یا نام دامنه سرور پایگاه داده است و شماره پورت شماره پورتی است که سرور پایگاه داده روی آن گوش می‌دهد.
  5. /dbname: این نام پایگاه داده است که باید به آن وصل شویم.
  6. ?param1=true&param2=false: این بخش پارامترهای پرس و جو برای تعیین پارامترهای اتصال اضافی استفاده می‌شود. در این مثال، دو پارامتر وجود دارد.

این پارامترهای پرس و جو براساس نیازهای خاص درایور پایگاه داده و سرور پایگاه داده می‌توانند تنظیم شوند تا ویژگی‌ها یا رفتارهای خاص اتصال را پیکربندی کنند.

پارامترهای اتصال Postgres

postgres://postgres:password@localhost:5432/example?sslmode=disable

پارامترهای اتصال SQLite

sqlite3://path/to/database?query

پارامترهای اتصال MongoDB

mongodb://user:password@host:port/dbname?query

3.1 استفاده از CLI

3.1.1 استفاده پایه

برای استفاده از CLI، دستور زیر را اجرا کنید:

migrate -source file://path/to/migrations -database postgres://localhost:5432/database up 2

این دستور مهاجرت‌ها را از منبع مشخص‌شده به پایگاه داده داده شده اعمال می‌کند. عدد "2" تعداد مهاجرت‌هایی است که باید اعمال شود.

3.1.2 استفاده از Docker

Go Migrate همچنین می‌تواند با Docker استفاده شود. دستور زیر را اجرا کنید:

docker run -v {{ migration dir }}:/migrations --network host migrate/migrate -path=/migrations/ -database postgres://localhost:5432/database up 2

این دستور Go Migrate را در یک ظرف Docker اجرا می‌کند و مهاجرت‌ها را از منبع مشخص‌شده به پایگاه داده داده شده اعمال می‌کند.

3.2 استفاده در پروژه Go خود

برای استفاده از Go Migrate در پروژه Go خود، نیاز است که بسته‌ها و کتابخانه‌های مورد نیاز را وارد کنید. در اینجا یک مثال آمده است:

import (
    "github.com/golang-migrate/migrate/v4"
    _ "github.com/golang-migrate/migrate/v4/database/postgres"
    _ "github.com/golang-migrate/migrate/v4/source/github"
)

func main() {
    m, err := migrate.New(
        "github://mattes:personal-access-token@mattes/migrate_test",
        "postgres://localhost:5432/database?sslmode=enable")
    m.Steps(2)
}

این کد Go Migrate را با منبع و پایگاه داده مشخص شده مقداردهی اولیه کرده و سپس 2 مهاجرت را با استفاده از متد Steps اعمال می‌کند.

اگر می‌خواهید از یک مشتری پایگاه داده موجود استفاده کنید، لطفا به مثال زیر مراجعه کنید:

import (
    "database/sql"
    _ "github.com/lib/pq"
    "github.com/golang-migrate/migrate/v4"
    "github.com/golang-migrate/migrate/v4/database/postgres"
    _ "github.com/golang-migrate/migrate/v4/source/file"
)

func main() {
    db, err := sql.Open("postgres", "postgres://localhost:5432/database?sslmode=enable")
    driver, err := postgres.WithInstance(db, &postgres.Config{})
    m, err := migrate.NewWithDatabaseInstance(
        "file:///migrations",
        "postgres", driver)
    m.Up()
}

این کد بسته‌های مورد نیاز را وارد می‌کند و مشتری پایگاه داده را با استفاده از بسته sql مقداردهی اولیه می‌کند. سپس یک نمونه جدید Go Migrate با استفاده از متد NewWithDatabaseInstance ایجاد می‌کند و منبع و درایور پایگاه داده را مشخص می‌کند. در نهایت، مهاجرت را با استفاده از متد Up اعمال می‌کند.

4. درایورهای پایگاه داده پشتیبانی شده

Go Migrate از چندین درایور پایگاه داده از جمله استفاده می‌کند:

  • PostgreSQL
  • PGX v4
  • PGX v5
  • Redshift
  • Ql
  • Cassandra
  • SQLite
  • SQLite3
  • SQLCipher
  • MySQL/MariaDB
  • Neo4j
  • MongoDB
  • CrateDB
  • Shell
  • Google Cloud Spanner
  • CockroachDB
  • YugabyteDB
  • ClickHouse
  • Firebird
  • MS SQL Server

5. منابع مهاجرت پشتیبانی شده

Go Migrate از چندین منبع مهاجرت از جمله استفاده می‌کند:

  • سیستم فایل: مهاجرت‌ها را از سیستم فایل محلی می‌خواند.
  • io/fs: مهاجرت‌ها را با استفاده از بسته io/fs Go می‌خواند.
  • Go-Bindata: مهاجرت‌ها را از داده دودویی تعبیه شده با استفاده از بسته jteeuwen/go-bindata می‌خواند.
  • pkger: مهاجرت‌ها را از داده دودویی تعبیه شده با استفاده از بسته markbates/pkger می‌خواند.
  • GitHub: مهاجرت‌ها را از یک مخزن GitHub از راه دور می‌خواند.
  • GitHub Enterprise: مهاجرت‌ها را از یک مخزن Enterprise GitHub از راه دور می‌خواند.
  • Bitbucket: مهاجرت‌ها را از یک مخزن Bitbucket از راه دور می‌خواند.
  • Gitlab: مهاجرت‌ها را از یک مخزن Gitlab از راه دور می‌خواند.
  • AWS S3: مهاجرت‌ها را از Amazon Web Services S3 می‌خواند.
  • ذخیره سازی ابری Google: مهاجرت‌ها را از ذخیره سازی Google Cloud Platform می‌خواند.

بسته به نیازهای پروژه‌تان، می‌توانید فایل‌های مهاجرت پایگاه داده را در منابع ذخیره سازی پشتیبانی شده مذکور برای فایل نگهداری کنید.

6. فایل‌های مهاجرت

فایل‌های مهاجرت در Go Migrate دارای فرمت نام و محتوا خاصی هستند.

6.1 فرمت نام فایل مهاجرت

هر مهاجرت شامل یک فایل مهاجرت "up" و یک فایل مهاجرت "down" متناظر است. نام فایل‌های مهاجرت باید با فرمت زیر سازگار باشند:

{version}_{title}.up.{extension}
{version}_{title}.down.{extension}

version یک شماره یکتا است که نشان‌دهنده ترتیب اعمال مهاجرت‌ها است. title یک توضیح اختیاری از مهاجرت است. extension بستگی به سیستم پایگاه داده مورد استفاده دارد (به عنوان مثال، برای نوع‌های SQL از ‍.sql استفاده کنید).

6.2 فرمت محتوای فایل مهاجرت

محتوای فایل‌های مهاجرت به دلیل سیستم پایگاه داده مختلف متفاوت است، معمولاً شامل نوشتن مستقیم SQL می‌شود.

به عنوان مثال، محتوای دو فایل مهاجرت به شرح زیر است:

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

فایل مهاجرت 000001_create_users_table.up.sql

CREATE TABLE IF NOT EXISTS users(
   user_id serial PRIMARY KEY,
   username VARCHAR (50) UNIQUE NOT NULL,
   password VARCHAR (50) NOT NULL,
   email VARCHAR (300) UNIQUE NOT NULL
);

فایل مهاجرت 000001_create_users_table.down.sql، فایل "down" به طور اصلی برای واگردانی عملیات قبلی استفاده می‌شود، معمولاً برای اهدای عملیات.

DROP TABLE IF EXISTS users;

6.3 قابل برگشت بودن مهاجرت

نوشتن مهاجرت‌های قابل برگشت به عنوان بهترین روش مدنظر قرار می‌گیرد. این بدان معناست که مهاجرت‌های "up" و "down" باید قادر باشند به هر نسخه‌ای اجرا شوند و به طور موثر وضعیت پایگاه داده را بازسازی و پاکسازی کنند.

برای اطمینان از قابل برگشت بودن، هر مهاجرت باید فایل مهاجرت "up" و "down" متناظر خود را داشته باشد. فایل مهاجرت "up" حاوی عملیات برای اعمال مهاجرت است، در حالی که فایل مهاجرت "down" شامل عملیات برای لغو مهاجرت می‌باشد.

7. استفاده از MySQL

Go Migrate امکاناتی برای پایگاه داده‌های MySQL فراهم می‌کند. برای اتصال به پایگاه داده MySQL، URL پایگاه داده باید به شکل زیر باشد:

mysql://user:password@tcp(host:port)/dbname?query

URL می‌تواند شامل پارامترهای پرس و جو، مانند نام جدول مهاجرت، پارامترهای TLS و غیره باشد. برای مشاهده لیست کاملی از پارامترهای پرس و جو، لطفا به Go Migrate MySQL documentation مراجعه کنید.

7.1 پارامترهای پرس و جو URL

  • x-migrations-table: نام جدول مهاجرت.
  • x-no-lock: با مقدار true برای رد کردن دستورات GET_LOCK/RELEASE_LOCK استفاده می‌شود. برای نسخه‌های چند مستر MySQL مفید است.
  • x-statement-timeout: هر عملیاتی را که از تعداد مشخص شده میلی‌ثانیه تجاوز کند، متوقف می‌کند.
  • dbname: نام پایگاه داده برای اتصال.
  • user: کاربر برای ورود.
  • password: رمز عبور کاربر.
  • host: میزبان برای اتصال.
  • port: پورت برای متصل شدن.
  • tls: پارامترهای اتصال رمزنگاری TLS/SSL.
  • x-tls-ca: مکان فایل CA (اعتبار‌دهنده پروتکل امنیتی)
  • x-tls-cert: مکان فایل گواهینامه مشتری.
  • x-tls-key: مکان فایل کلید خصوصی.
  • x-tls-insecure-skip-verify: آیا از SSL استفاده شود یا خیر.

7.2 استفاده از کلاینت‌های موجود

اگر قصد دارید از Go Migrate با یک کلاینت MySQL موجود استفاده کنید، اطمینان حاصل کنید که هنگام ایجاد کلاینت از پارامتر multiStatements=true استفاده کنید. یک مثال به شرح زیر است:

package main

import (
    "database/sql"
    
    _ "github.com/go-sql-driver/mysql"
    "github.com/golang-migrate/migrate/v4"
    "github.com/golang-migrate/migrate/v4/database/mysql"
    _ "github.com/golang-migrate/migrate/v4/source/file"
)

func main() {
    db, _ := sql.Open("mysql", "user:password@tcp(host:port)/dbname?multiStatements=true")
    driver, _ := mysql.WithInstance(db, &mysql.Config{})
    m, _ := migrate.NewWithDatabaseInstance(
        "file:///migrations",
        "mysql", 
        driver,
    )
    
    m.Steps(2)
}

این کد پکیج‌های مورد نیاز را import می‌کند، یک کلاینت پایگاه داده MySQL ایجاد می‌کند و Go Migrate را با نمونه پایگاه داده مقداردهی اولیه می‌کند. سپس دو مهاجرت را با استفاده از متد Steps اعمال می‌کند.