そごうソフトウェア研究所

SOA、開発プロセス、ITアーキテクチャなどについて書いています。Twitterやってます@rsogo

Android SQLiteデータベースのテーブル変更はこうやる

データベースのテーブルのカラム追加や、定義の変更っていうのはAndoroidアプリでも大変なことですよねぇ。

android.database.sqlite.SQLiteOpenHelperにデータベースのバージョンを上げたときに呼び出されるメソッド、onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)が用意されているので、SQLiteOpenHelperを継承して実装します。


このメソッドはアプリが起動して最初にデータベースを使う時に、データベースのバージョンが変わっていれば呼び出されます。
具体的にはContentProviderが初期化(onCreateメソッド)される時にSQLiteOpenHelperを継承したクラスをインスタンス化しますが、その時にDBのバージョンを指定します。

	@Override
	public boolean onCreate() {
		
		SQLiteOpenHelper dbHeler =new DBHelper(
				getContext(),
				DB_NAME,
				null,
				DB_VERSION,
				new TaskTable());
		
		db = dbHeler.getWritableDatabase();
		return (db != null);
	}

このときに、バージョンアップ前のバージョンと、アプリをバージョンアップした時に指定してきたDBのバージョン(上のコードではDB_VERSIONがバージョンの定数定義)が違うことが分かるのです。逆に言えばアプリ開発者はこのDBバージョンを上手く使い分けてあげる必要があります。


onUpgradeメソッドのoldVersionには今アプリ内でデータを保存しているデータベースのバージョン、newVersionには新しくバージョンアップしたアプリのデータベースのバージョンが入ります。

今アプリ内に持っているデータが必要無い場合は、今あるテーブルを削除して、もう一回作り直せばOK。


でも、一度リリースしてしまえば、データが必要無い場合なんてないですよね。一番多いケースのカラム追加であれば、次のようにalter tableでカラム追加。もともと入っているデータ用にデフォルト値をしてしてあげればOK。

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// DBバージョンアップ時のデータ移行を実装
		if (oldVersion < newVersion) {
			if (oldVersion == 3) {
				
				db.execSQL(
						"alter table " + TaskTable.DB_TABLE_NAME +
						" add isUploaded boolean default 'false'
						);
	
			}
			if (oldVersion == 3 || oldVersion == 4) {
				
				db.execSQL(
						"alter table " + TaskTable.DB_TABLE_NAME +
						" add idOfServer text"
						);
			}
		}
	}


テーブルの定義ががらっと変わってしまうような大きな変更の場合は、一旦Selectしてテーブル作成後に新しい定義でInsertするようなデータ移行を考えないと行けないですね。


なんにしてもデータベースの変更は慎重に。