最近不得不考慮關(guān)于數(shù)據(jù)庫(kù)遷移的問題,原先用了種很不好的處理方式(每次版本升級(jí)就刪除本地?cái)?shù)據(jù)庫(kù),太傻),于是開始考慮下如何遷移數(shù)據(jù)庫(kù)。
項(xiàng)目使用的 FMDB ,除了使用 Core Data 外,這就是最好的了(最近好像又有了個(gè) realm )。
在 FMDB 介紹頁(yè)面,發(fā)現(xiàn)了 FMDBMigrationManager ,大喜。
看了半天文檔,搗鼓了半天才弄出來,一步步整理下。
0.安裝 FMDBMigrationManager
Podfile 文件:
platform :ios, "7.0"
pod 'FMDB'
pod 'FMDBMigrationManager'
使用pod install命令安裝
1.FMDBMigrationManager 創(chuàng)建數(shù)據(jù)庫(kù)
FMDBMigrationManager *manager = [FMDBMigrationManager managerWithDatabaseAtPath:[YMDatabaseHelper databasePath] migrationsBundle:[NSBundle mainBundle]];
其中[YMDatabaseHelper databasePath]是數(shù)據(jù)庫(kù)路徑
2.創(chuàng)建遷移表
BOOL resultState = [manager createMigrationsTable:&error];
創(chuàng)建的遷移表名稱為:schema_migrations
3.創(chuàng)建 .sql 文件
該文件用來存儲(chǔ)每次升級(jí)使用的 SQL 語(yǔ)句。
FMDBMigrationManager 建議我們使用時(shí)間戳來作為版本號(hào),使用下面的命令生成一個(gè)文件:
touch "`ruby -e "puts Time.now.strftime('%Y%m%d%H%M%S%3N').to_i"`"_CreateMyAwesomeTable.sql
我生成的文件名為:20150420170044940_CreateMyAwesomeTable.sql,其中20150420170044940 為遷移的版本號(hào)標(biāo)識(shí)。
我們?cè)?20150420170044940_CreateMyAwesomeTable.sql文件中創(chuàng)建一個(gè)用戶表,寫入:
CREATE TABLE User(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
name TEXT
);
4.遷移函數(shù)
FMDBMigrationManager *manager = [FMDBMigrationManager managerWithDatabaseAtPath:[YMDatabaseHelper databasePath] migrationsBundle:[NSBundle mainBundle]];
BOOL resultState = NO;
NSError *error = nil;
if (!manager.hasMigrationsTable) {
resultState = [manager createMigrationsTable:&error];
}
resultState = [manager migrateDatabaseToVersion:UINT64_MAX progress:nil error:&error];//遷移函數(shù)
NSLog(@"Has `schema_migrations` table?: %@", manager.hasMigrationsTable ? @"YES" : @"NO");
NSLog(@"Origin Version: %llu", manager.originVersion);
NSLog(@"Current version: %llu", manager.currentVersion);
NSLog(@"All migrations: %@", manager.migrations);
NSLog(@"Applied versions: %@", manager.appliedVersions);
NSLog(@"Pending versions: %@", manager.pendingVersions);
UINT64_MAX 表示把數(shù)據(jù)庫(kù)遷移到最大的版本
運(yùn)行項(xiàng)目,打印出如下內(nèi)容:
2015-04-20 20:50:19.033 YMFMDatabase[12654:1326201] Has `schema_migrations` table?: YES
2015-04-20 20:50:19.036 YMFMDatabase[12654:1326201] Origin Version: 20150420170044940
2015-04-20 20:50:19.036 YMFMDatabase[12654:1326201] Current version: 20150420170044940
2015-04-20 20:50:19.037 YMFMDatabase[12654:1326201] All migrations: (
"<FMDBFileMigration: 0x17003b4c0>"
)
2015-04-20 20:50:19.037 YMFMDatabase[12654:1326201] Applied versions: (
20150420170044940
)
2015-04-20 20:50:19.038 YMFMDatabase[12654:1326201] Pending versions: (
)
用 iFunBox 查看下是不是創(chuàng)建了一個(gè) User 表,里面含有 id、name 字段。以及 FMDBMigrationManager 生成的 schema_migrations 表。
5.創(chuàng)建第二個(gè) .sql 文件
先用上方命令:
touch "`ruby -e "puts Time.now.strftime('%Y%m%d%H%M%S%3N').to_i"`"_CreateMyAwesomeTable.sql```
生成,我生成的是:``20150420170557221_CreateMyAwesomeTable.sql``。
第二個(gè) sql 文件,里面創(chuàng)建一個(gè)新表名字為 ``Grouping``,為原先的 ``User`` 表添加郵箱字段:``email``。.sql 文件修改如下:
CREATE TABLE Grouping(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
name TEXT
);
ALTER TABLE User ADD email TEXT;
##6.創(chuàng)建第三個(gè) .sql 文件
生成同上,文件內(nèi)容是為 ``Grouping`` 表添加備注字段 ``remark``:
文件內(nèi)容:
ALTER TABLE Grouping ADD remark TEXT;
OK,直接運(yùn)行項(xiàng)目,看看是不是創(chuàng)建了 ``Grouping`` 表,里面含有``id``,``name``,``remark``字段,以及 ``User`` 表里面是不是添加了 ``email`` 字段。
##7.遇到的問題
中間我自己做 Demo 時(shí),試圖刪除表中的某列,比如刪除 ``User`` 表中的 ``name`` 列,但是不能成功,Google 了下發(fā)現(xiàn)[答案](http://stackoverflow.com/questions/8442147/how-to-delete-or-add-column-in-sqlite)。
>SQLite supports a limited subset of ALTER TABLE. The ALTER TABLE command in SQLite allows the user to rename a table or to add a new column to an existing table. It is not possible to rename a column, remove a column, or add or remove constraints from a table.
解釋下:就是說 ``SQLite`` 對(duì) ``ALERT TABLE`` 命令受限制,``SQLite`` 中的 ``ALERT TABLE`` 命令只能允許用戶重命名表或者添加新列,不能重命名列或者刪除列或者刪除約束。