Saya memelihara aplikasi yang secara berkala perlu memperbarui database sqlite dan memigrasi database lama ke skema baru dan inilah yang saya lakukan:
Untuk melacak versi database, saya menggunakan variabel versi pengguna bawaan yang disediakan sqlite (sqlite tidak melakukan apa pun dengan variabel ini, Anda bebas menggunakannya sesuka Anda). Ini dimulai dari 0, dan Anda bisa mendapatkan / mengatur variabel ini dengan pernyataan sqlite berikut:
> PRAGMA user_version;
> PRAGMA user_version = 1;
Saat aplikasi dimulai, saya memeriksa versi pengguna saat ini, menerapkan perubahan apa pun yang diperlukan untuk memperbarui skema, dan kemudian memperbarui versi pengguna. Saya membungkus pembaruan dalam transaksi sehingga jika ada yang salah, perubahan tidak dilakukan.
Untuk membuat perubahan skema, sqlite mendukung sintaks "ALTER TABLE" untuk operasi tertentu (mengganti nama tabel atau menambahkan kolom). Ini adalah cara mudah untuk memperbarui tabel yang sudah ada. Lihat dokumentasinya di sini: http://www.sqlite.org/lang_altertable.html . Untuk menghapus kolom atau perubahan lain yang tidak didukung oleh sintaks "ALTER TABLE", saya membuat tabel baru, memindahkan tanggal ke dalamnya, melepaskan tabel lama, dan mengganti nama tabel baru ke nama asli.
application_id
adalah bit ekstra untuk mengidentifikasi format file berdasarkanfile
utilitas misalnya, bukan untuk versi database.Jawaban dari Just Curious sudah mati (Anda mengerti maksud saya!), Dan itulah yang kami gunakan untuk melacak versi skema database yang saat ini ada di aplikasi.
Untuk menjalankan migrasi yang perlu terjadi agar user_version cocok dengan versi skema aplikasi yang diharapkan, kami menggunakan pernyataan switch. Berikut adalah contoh potongan dari tampilan ini di Strip aplikasi kami :
sumber
toVersion
kode Anda? Bagaimana penanganannya ketika Anda menggunakan versi 0 dan ada dua versi lagi setelah itu. Ini berarti Anda harus bermigrasi dari 0 ke 1 dan dari 1 ke 2. Bagaimana Anda menangani ini?break
pernyataan di dalamswitch
, jadi semua migrasi selanjutnya juga akan terjadi.Izinkan saya membagikan beberapa kode migrasi dengan FMDB dan MBProgressHUD.
Inilah cara Anda membaca dan menulis nomor versi skema (ini mungkin bagian dari kelas model, dalam kasus saya ini adalah kelas tunggal yang disebut Database):
Berikut
[self database]
metode yang membuka database dengan malas:Dan berikut adalah metode migrasi yang dipanggil dari pengontrol tampilan:
Dan inilah kode pengontrol tampilan root yang memanggil migrasi, menggunakan MBProgressHUD untuk menampilkan bezel kemajuan:
sumber
schema_version
pragma biasanya bukan sesuatu yang ditangani orang juga.Solusi terbaik IMO adalah membangun kerangka kerja peningkatan SQLite. Saya memiliki masalah yang sama (di dunia C #) dan saya membangun kerangka kerja saya sendiri. Anda dapat membacanya di sini . Ini bekerja dengan sempurna dan membuat upgrade saya (sebelumnya mimpi buruk) bekerja dengan sedikit usaha di pihak saya.
Meskipun perpustakaan diimplementasikan dalam C #, ide-ide yang disajikan di sana juga akan berfungsi dengan baik dalam kasus Anda.
sumber
1
. Buat/migrations
folder dengan daftar migrasi berbasis SQL, di mana setiap migrasi terlihat seperti ini:/migrations/001-categories.sql
/migrations/002-posts.sql
2
. Buat tabel db yang berisi daftar migrasi yang diterapkan, misalnya:3
. Perbarui logika bootstrap aplikasi sehingga sebelum dimulai, ia mengambil daftar migrasi dari/migrations
folder dan menjalankan migrasi yang belum diterapkan.Berikut ini contoh yang diterapkan dengan JavaScript: Klien SQLite untuk Aplikasi Node.js
sumber
Beberapa tips ...
1) Saya sarankan untuk meletakkan semua kode untuk memigrasi database Anda ke dalam NSOperation dan menjalankannya di thread latar belakang. Anda bisa menampilkan UIAlertView kustom dengan spinner saat database sedang dimigrasi.
2) Pastikan Anda menyalin database Anda dari bundel ke dalam dokumen aplikasi dan menggunakannya dari lokasi itu, jika tidak, Anda hanya akan menimpa seluruh database dengan setiap pembaruan aplikasi, lalu memigrasi database baru yang kosong.
3) FMDB bagus, tetapi metode executeQuery-nya tidak dapat melakukan kueri PRAGMA karena alasan tertentu. Anda harus menulis metode Anda sendiri yang menggunakan sqlite3 secara langsung jika Anda ingin memeriksa versi skema menggunakan PRAGMA user_version.
4) Struktur kode ini akan memastikan bahwa pembaruan Anda dijalankan secara berurutan, dan semua pembaruan dijalankan, tidak peduli berapa lama pengguna berjalan di antara pembaruan aplikasi. Ini bisa difaktorisasi lebih jauh, tapi ini adalah cara yang sangat sederhana untuk melihatnya. Metode ini dapat dijalankan dengan aman setiap kali data tunggal Anda dibuat, dan hanya memerlukan biaya satu kueri db kecil yang hanya terjadi sekali per sesi jika Anda menyiapkan data tunggal dengan benar.
sumber
Jika Anda mengubah skema database dan semua kode yang menggunakannya di lockstep, seperti yang mungkin terjadi di aplikasi yang disematkan dan yang terletak di ponsel, masalahnya sebenarnya terkendali dengan baik (tidak ada yang sebanding dengan mimpi buruk yaitu migrasi skema pada DB perusahaan yang mungkin melayani ratusan aplikasi - tidak semuanya di bawah kendali DBA juga ;-).
sumber
Untuk .net Anda dapat menggunakan lib:
EntityFrameworkCore.Sqlite.Migrations
Ini sederhana, jadi untuk platform lain Anda dapat dengan mudah menerapkan perilaku yang sama seperti di lib.
sumber