Tutorial Codeigniter 4: Migrasi Database
Sebelum kita masuk membahas tentang CRUD di Codeigniter 4, kita bahas dulu tentang migrasi database.
Apa itu migrasi database?
Mengapa kita membutuhkan migrasi database?
..dan bagaimana cara migrasi database di Codeigniter 4?
Mari kita mulai.
Apa itu Migrasi Database?
Migrasi artinya berpindah.
Migrasi manusia = perpindahan manusia dan menetap di suatu tempat.
Nah, kalau migrasi database apa?
Migrasi database adalah perpindahan database dari suatu tempat ke tempat yang lain. Misalnya database di localhost ke server production.
Perpindahan ini biasanya kita lakukan dengan manual, yakni dengan cara dump dan export database di localhost.. lalu mengimpornya di server production.
Cara ini memang bisa dilakukan.
Tapi masalahnya:
Jika nanti kita bekerja dengan tim.. Saat perubahan skema database terjadi, maka tim yang lain juga harus mengikuti.
Mau tidak mau, kita harus dump dan export skema milik kita dan memberikan ke semua anggota tim yang terlibat. Belum lagi versi database yang mereka gunakan beragam.
Bisa jadi ini akan menghambat kita dalam membuat aplikasi.
Contoh kasus lain:
Karena itulah, kita membutuhkan migrasi database agar bisa menyimpan semua perubahan sekema yang kita lakukan.
Salah satu program untuk melakukan migrasi database yang bisa digunakan di PHP adalah Spinx.
Buat kamu yang tertarik dengan Spinx, bisa baca-baca di:
Namun, pada tutorial ini.. kita tidak akan menggunakan Spinx, karena Codeigniter sendiri udah punya fitur untuk migrasi database.
Lalu, bagaimana cara menggunakannya?
Migrasi Database di Codeigniter
Migrasi database sebelumnya (pada Codeigniter 3) dilakukan dengan class CI_Migration
, lalu memanggil class tersebut di Controller.
Pada Codeigniter 4.. kita sudah disediakan program khusus, yakni melalui spark
.
Perintah-perintah untuk membuat migrasi database dengan spark
, bisa kita lihat dengan perintah php spark --help
.
Ketujuh perintah inilah yang akan kita gunakan untuk membuat migrasi database. Berikut ini penjelasannya:
db:create
untuk membuat database baru;db:table
untuk melihat informasi tabel;db:seed
untuk membuat data awal (benih data);migrate
untuk melakukan migrasi (menjalankan methodup()
);migrate:create
ataumake:migration
untuk membuat file migrasi;migrate:refresh
untuk melakukan rollback dan melakukan migrasi perubahan terbaru;migrate:rollback
untuk melakukan rollback pada versi tertentu (menjalankan methoddown()
);migrate:status
untuk melihat status migrasi;make:seeder
untuk membuat file seeder.
Jika kamu bingung dengan cara menggunakan perintah tersebut, bisa lihat bantuannya dengan perintah:
php spark help <perintah>
Contoh:
php spark help migrate:create
Maka akan ditampilkan cara menggunaknya.
Mungkin akan lebih jelas, jika kita mencobanya sendiri.
Baiklah..
Mari kita coba!
Tapi sebelum itu, lakukan dulu:
Konfigurasi Database di Codeigniter 4
Pertama, jangan lupa rename file env
menjadi .env
agar bisa dibaca di CI.
Kemudian buka file .env
dan ubahlah konfigurasi database menjadi seperti ini:
#------------------------------------------------------------------
# DATABASE
#------------------------------------------------------------------
database.default.hostname = localhost
database.default.database = ci_news
database.default.username = root
database.default.password =
database.default.DBDriver = MySQLi
Untuk username
dan password
, sesuaikan dengan username
dan password
pada server MySQL yang kamu gunakan.
Sebagai contoh:
Saya sudah pernah mengubah username dan password di server MySQL saya dengan admin
dan password 123
, maka dikonfigurasi saya harus mengisi seperti ini:
#------------------------------------------------------------------
# DATABASE
#------------------------------------------------------------------
database.default.hostname = localhost
database.default.database = ci_news
database.default.username = admin
database.default.password = 123
database.default.DBDriver = MySQLi
Jika kita salah memasukkan username dan password, bisa jadi aplikasi tidak akan bisa terhubung dengan server database.
Setelah itu, buatlah database baru dengan nama ci_news
. Ini bisa dilakukan melalui command line atau Phpmyadmin.
Membuat database baru dengan spark
:
Jalankan perintah ini untuk membuat database baru.
php spark db:create ci_news
Perintah ini akan membuat database baru dengan nama ci_news
.
Selain menggunakan cara ini, kamu juga bisa membuat database dari Phpmyadmin.
Membuat database baru melalui Phpmyadmin:
..dam jika kamu ingin membuat database dari command line:
Buka shell MySQL, lalu ketik perintah berikut.
CREATE DATABASE ci_news;
Selanjutnya, kita bisa mulai membuat migrasi.
Membuat Migrasi untuk Tabel News
Pertama kita akan membuat sekema untuk tabel news
. Sebenarnya akan lebih gampang jika kita sudah memiliki rancangan sekema atau ERD.
Berikut ini ERD sementara untuk project ci-news
.
Catatan: Kita akan fokus mengerjakan untuk tabel
news
saja dulu. Untuk tabel yang lainnya bisa diabaikan atau kalau mau dikerjakan sendiri juga boleh.
Oke sekarang buka kembali project ci-news
yang sudah kita buat di
tutorial sebelumnya.
Kemudian ketik perintah berikut untuk membuat file migrasi:
php spark migrate:create news
Perintah ini akan membuat file baru dengan nama 2020-11-23-053942_news.php
di dalam folder app/Database/Migration
.
Tanggal dan waktu di awal nama file menandakan versi dari migrasi.
Berikut ini adalah isi file 2020-11-23-053942_news.php
.
<?php namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class News extends Migration
{
public function up()
{
//
}
//------------------------------------------------------
public function down()
{
//
}
}
Pada kode ini terdapat class News
yang merupakan turunan dari class Migration
.
Pada class News
terdapat dua method, yakni up()
dan down()
. Method ini nantinya akan dijalankan saat melakukan migrasi.
Method up()
akan dijalankan saat melakukan migrasi, sedangkan down()
saat melakukan rollback.
Tips: contoh di atas menggunakan
news
sebagai nama file migrasi. Ada juga yang menyarankan sebaiknya menggunakan nama yang deskriptif agar memudahkan. Misalnya seperticreate_news_table
,add_views_to_news_table
, dsb.
Oke..
Sekarang mari kita buat skema untuk tabel News. Silakan ubah kode pada file 2020-11-23-053942_news.php
menjadi seperti ini:
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class News extends Migration
{
public function up()
{
// Membuat kolom/field untuk tabel news
$this->forge->addField([
'id' => [
'type' => 'INT',
'constraint' => 5,
'unsigned' => true,
'auto_increment' => true
],
'title' => [
'type' => 'VARCHAR',
'constraint' => '255'
],
'author' => [
'type' => 'VARCHAR',
'constraint' => 100,
'default' => 'John Doe',
],
'content' => [
'type' => 'TEXT',
'null' => true,
],
'status' => [
'type' => 'ENUM',
'constraint' => ['published', 'draft'],
'default' => 'draft',
],
]);
// Membuat primary key
$this->forge->addKey('id', TRUE);
// Membuat tabel news
$this->forge->createTable('news', TRUE);
}
//-------------------------------------------------------
public function down()
{
// menghapus tabel news
$this->forge->dropTable('news');
}
}
Penjelasan kode:
Perhatikan pada method up()
, pertama kita membuat field terlebih dahulu baru membuat tabel.
Field dibuat dengan fungsi $this->forge->addField()
dan memberikan parameter berupa array yang berisi data dari field. Selain dalam bentuk array, bisa juga dalam bentuk string SQL seperti ini: 1
$this->forge->addField([
'id INT(5)',
'title VARCHAR(255)'
]);
Bahkan juga bisa digabung, string SQL dan array.
Selanjutnya kita membuat primary key dengan fungsi:
$this->forge->addKey('id', TRUE);
Parameter TRUE
berfungsi untuk menyatakan key yang dibuat adalah Primary Key. Jika tidak diberikan TRUE
maka akan dibuat menjadi key biasa atau foreign key.
Terakhir, kita membuat tabel dengan fungsi:
$this->forge->createTable('news', TRUE);
Nilai TRUE
berfungsi untuk mengecek apakah tabel sudah ada di database atau belum, jika ada maka tidak dilakukan pembuatan tabel. Jika kita tidak memberikan nilai TRUE
, maka tabel akan tetap dibuat.. meskipun sudah ada.
Terakhir kita menghapus tabel dengan fungsi:
$this->forge->dropTable('news');
Karena kita menulisnya di dalam method down()
, maka ini nantinya akan dipanggil saat kita melakukan rollback.
Oke, sekarang mari kita coba lakukan migrasi pertama.
Lakukan migrasi dengan perintah:
php spark migrate
Jika tidak ada error..
Maka migrasi berhasil dilakukan.
Sekarang coba cek database melalui Phpmyadmin, pasti di sana sudah ada dua tabel, yakni tabel migrations
dan tabel news
.
Tabel migrations
adalah tabel yang otomatis dibuat untuk menyimpan versi migrasi yang sudah dilakukan. Lalu tabel news
adalah tabel yang kita buat berdasarkan file migrasi.
Coba buka tabel migrations
, di sana akan ada data migrasi.
Terdapat beberapa kolom:
id
merupakan id primary key;version
versi dari file migrasi dibuat dalam bentuk tanggal dan waktu;class
file class untuk migrasi;group
group yang digunakan, adadefault
,test
,production
, dll. Kita juga bisa membuat group sendiri;namespace
name space yang digunakan;time
waktu dalam format unix time stamp;batch
nomer batch yang menyatakan nomer kloter migrasi;
Nomer batch
ini akan bertambah setiap kita melakukan migrasi yang baru. Karena ini migrasi pertama yang kita lakukan, maka nomornya adalah 1
.
Jika kita membuat file migrasi baru dan menjalankan perintah php spark migrate
, maka migrasi yang baru akan memiliki nomer 2
.
Bagaimana Kalau ada Perubahan Skema?
Ada dua cara yang bisa dilakukan:
Pertama, membuat file migrasi baru dan menuliskan perubahannya di sana, lalu melakukan migrasi lagi.
Cara pertama ini cocok dilakukan jika kita sudah punya data, karena perubahannya akan bisa di-rollback.
Kedua, bisa melakukan rollback, lalu mengubah file migrasi yang sudah ada dan melakukan migrasi kembali atau ini bisa dipersingkat dengan migrate:refresh
.
Cara kedua ini gampang dilakukan dan cocok dilakukan untuk migrasi awal. Namun kurang cocok dilakukan untuk aplikasi yang sudah punya data dan sudah melakukan migrasi berkali-kali, karena akan berpotensi menghapus data.
Kalau menurut saya, cara pertama lebih aman dibandingkan dengan cara kedua. Tapi tidak masalah jika migrasi ini dilakukan di server development.
Oke, sekarang mari kita coba kedua-duanya..
Pertama kita akan coba cara yang paling gampang, yakni migrate:refresh
.
Ubahlah kode pada file 2020-11-23-053942_news.php
menjadi seperti ini:
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class News extends Migration
{
public function up()
{
// Membuat kolom/field untuk tabel news
$this->forge->addField([
'id' => [
'type' => 'INT',
'constraint' => 5,
'unsigned' => true,
'auto_increment' => true
],
'title' => [
'type' => 'VARCHAR',
'constraint' => '255'
],
'author' => [
'type' => 'VARCHAR',
'constraint' => 100,
'default' => 'John Doe',
],
'content' => [
'type' => 'TEXT',
'null' => true,
],
'status' => [
'type' => 'ENUM',
'constraint' => ['published', 'draft'],
'default' => 'draft',
],
'created_at DATETIME DEFAULT CURRENT_TIMESTAMP'
]);
// Membuat primary key
$this->forge->addKey('id', TRUE);
// Membuat tabel news
$this->forge->createTable('news', TRUE);
}
//---------------------
public function down()
{
// menghapus tabel news
$this->forge->dropTable('news');
}
}
Pada kode ini kita menambahkan kolom created_at
dengan tipe DATETIME
dan nilai default CURRENT_TIMESTAMP
.
Setelah itu, jalankan perintah:
php spark migrate:refresh
Coba perhatikan output dari perintah ini:
Dia melakukan rollback ke batch 0
, lalu melakukan migrasi ulang ke batch 1
.
Sekarang coba cek kembali tabel news
, di sana akan ada kolom baru bernama created_at
.
Jika tabel news
sudah punya data, maka data tersebut akan dihapus karena dilakukan rollback
(drop table).
Inilah mengapa cara ini kurang aman untuk aplikasi yang sudah punya data, tapi tidak masalah untuk dilakukan di awal.
Oke sekarang kita coba cara yang lain..
Misalkan, kita ingin menambahkan kolom slug
pada tabel news
, kita bisa membuat file migrasi baru dengan perintah:
php spark migrate:create alter_news
Kemudian mengisi file tersebut dengan kode berikut:
<?php namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class AlterNews extends Migration
{
public function up()
{
$this->forge->addColumn('news', [
'slug VARCHAR(100) UNIQUE'
]);
}
//--------------------------------------------------------
public function down()
{
$this->forge->dropColumn('news', 'slug');
}
}
Pada kode ini kita menambahkan kolom slug
pada tabel news
dengan tipe VARCHAR, ukurannya 100
dan bersifat unik (key unique).
Lalu pada method down()
, kita melakukan penghapusan kolom.
Setelah itu, coba lakukan migrasi dengan perintah:
php spark migrate
Jika tidak ada error..
Maka migrasi berhasil dilakukan.
Coba cek kembali tabel news
dari Phpmyadmin, maka akan ada kolom baru bernama slug
.
Coba juga untuk melihat isi tabel migrations
, di sana akan ada data baru dengan nomer batch 2
.
Jika kita melakukan rollback ke batch 1
, maka data dengan nomer batch 2
akan dihapus dan kondisi database akan kembali seperti saat batch 1
.
Gampang kan?
Nah sekarang pertanyaannya:
Apakah setiap membuat file migrasi baru, kita harus melakukan migrasi (php spark migrate
)?
Tidak harus, kita bisa membuat file migrasi sebanyak-banyaknya di awal. Misalnya aplikasi kita punya 10 tabel, maka kita bisa buat 10 file migrasi dulu baru melakukan migrasi.
Oh iya, jangan lupa untuk selalu mengecek status migrasi dengan perintah:
php spark migrate:status
Tujuannya untuk tahu migrasi apa saja yang sudah dilakukan.
Berikutnya kita akan membuat seed data awal.
Membuat Seed Data untuk News
Seed data adalah data awal untuk mengisi tabel. Seed data kadang kita butuhkan untuk mengetes, dan menyiapkan data yang diperlukan di awal seperti user pertama pada aplikasi.
Untuk membuat seed data, kita membutuhkan file seeder. File seeder ini dapat dibuat dengan perintah:
php spark make:seeder <nama_seed>
Contoh:
php spark make:seeder news
Maka kita akan memiliki file baru di dalam folder app/Database/Seeds
dengan nama news.php
.
Ubahlah isi file news.php
menjadi seperti ini:
<?php namespace App\Database\Seeds;
use CodeIgniter\Database\Seeder;
class News extends Seeder
{
public function run()
{
// membuat data
$news_data = [
[
'title' => 'Selamat datang di Codeigniter',
'slug' => 'codeigniter-intro',
'content' => 'Pengenalan Codeigniter untuk Pemula.'
],
[
'title' => 'Hello World',
'slug' => 'hello-world',
'content' => 'Hello World, ini contoh artikel'
],
[
'title' => 'Meetup komunitas Codeigniter Indonesia',
'slug' => 'codeigniter-meetup',
'content' => 'Seru sekali meetup perdana komunitas codeigniter..'
]
];
foreach($news_data as $data){
// insert semua data ke tabel
$this->db->table('news')->insert($data);
}
}
}
Perhatikan, pada method run()
kita membuat array yang berisi data yang akan disimpan dalam tabel news
.
Lalu kita menggunakan perulangan foreach untuk menyimpan semuanya. Jika hanya satu data saja, maka tidak perlu menggunakan perulangan.
Method run()
akan dijalankan ketika kita menjalankan perintah db:seed
.
Mari kita coba..
Jalankan seeder dengan perintah berikut:
php spark db:seed
Kemudian isi nama seeder.
Atau bisa juga dilakukan dengan langsung memberikan nama seeder di awal seperti ini:
php spark db:seed news
Maka sekarang tabel news akan memiliki data awal.
Apa Selanjutnya?
Sejauh ini kita sudah mengetahui cara melakukan migrasi di Codeigniter 4. Buat kamu yang baru pertama belajar tentang migrasi, mungkin akan bingung.
Tapi percayalah, kelak saat aplikasi kita pindah-pindah sever dan bekerja dengan tim.. migrasi ini akan terasa manfaatnya.
Selanjutnya silakan lanjut ke:
Untuk tutorial Codeigniter yang lainnya, cek di 📚 List Tutorial Codeigniter