FMDBでSQLite利用時の、DB Error: 1 “no such table: エラーについて


ある日、Xcodeのデバッグバーにこんな表示がでた。

既にいくつかのテーブルがはいったデータベースを参照して実行しているはずが、テーブルが存在しないというエラーだ。
このエラーでググって、検索結果を片っ端から試したが、ことごとく失敗に終わってしまった。
何か重大な勘違いをしているのではないかと思ったので、アプリケーションのビルド時におけるデータベースの扱い方についてまとめる。

前提

  • Mac用SQLiteクライアントLitaで作ったSelfPhoto.sqliteをマスターデータとして用意
  • VSCardというプロジェクトを用意
  • iOS で SQLite を簡単に扱うためのライブラリ、FMDBを利用

状況確認

まず、エラー時の状況をよく確認する。
アプリケーションをビルドした際、データベースSelfPhoto.sqliteの位置は当然ながらXcodeプロジェクト内ではなく、シミュレータもしくは実機の対象アプリケーション専用のサンドボックス(アプリケーション専用のディレクトリ)内で、Documentsディレクトリ以下に設置される。
場所は下記のとおり。

確認すると確かにSelfPhoto.sqliteが存在した。

スクリーンショット 2013-11-22 15.45.07

しかし、これをLitaで開いてみると何もテーブルが存在していない。0 kbだ。

スクリーンショット 2013-11-22 10.10.07

確かにXcodeにはマスターデータをドラッグアンドドロップしたはずなのに、何もはいっていない。
一体何がおこっているのか。

アプリケーションビルド時のデータベースの扱い

まず、iOSアプリケーションをビルドすると、Xcodeはアプリケーションをバンドルとしてパッケージ化する。

バンドル…関連のあるリソースをひとつの場所に集めた、ファイルシステム上のディレクトリ。iOSアプリケーションのバンドルには、アプリケーションの実行可能ファイルと支援用リソースファイル(アプリケーションアイコン、画像ファイル、ローカライズされたコンテンツなど)が含まれる。

データベースに関してはサンドボックス内のDocumentsディレクトリに設置される。
データベースをDocumentsディレクトリに設置する方法として、コード上で直接Documents以下にデータベースファイルを新規作成する処理を記述するか、先述のバンドル内からDocuments以下にコピーしてくる処理を記述しなければならないことが、いろいろ調べてみてわかった。

今回、マスターデータを利用するということで、コードで処理する前の準備として、バンドル内にマスターデータがはいったデータベースファイルを設置する必要があるようだ。
バンドル内へデータベースファイルを追加する方法は2つある。

1,データベースファイルをXcodeプロジェクト内に追加する際、下記のチェックをいれる。
スクリーンショット 2013-11-22 10.36.23

2,データベースファイルをXcodeプロジェクト内に追加した後、TARGETSのCopy Bundle Resourcesにデータベースファイルを追加する
方法1の際にチェックを入れ忘れていたときに利用。
下記画面上で、Copy Bundle Resources欄で+をクリックして対象データベースを追加する。

スクリーンショット 2013-11-22 11.01.43

もし、選択状態が解除されていることに気づかずに、そのままプロジェクトに追加してしまうと、プロジェクトには追加されるもののコンパイル対象には含まれないという状態になってしまう。

まとめ

今回のエラーの原因は

・コード上にデータベースをDocuments以下に新規作成する処理のみが記載され、テーブルを作成する処理が記載されていなかった。

このため、 空のデータベース(0 kb)が作成されただけで、何もテーブルが入っておらず、no such table…エラーが出た。

しかし、やりたかったことはマスターデータの入ったデータベースを反映させることなので、本質的な解決法は下記になる。

・マスターデータが入ったデータベースファイルをCopy Bundle Resourcesに設置し、コード上で、Documents以下にデータベースファイルの存在を確認後、存在しなければアプリケーションバンドルからコピーする処理を記述する。

データベースファイルを新規作成したり、コピーしたりするコード例は他のいろいろなサイトに記載されているので、ググッてみて欲しい。

以上。


投稿者: しんじ

ベトナムでオフショア開発会社経営中 www.bit-vietnam.com 。サービス開発が趣味。web系は主にPHPで、スマホアプリはswiftで。最近はエンジニア向けの英語勉強webアプリ エングリッシュ e-lish.io を作りました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です