Flutter: バックアップした「hive」のファイルをインポート(リストア)して上書きしても、データが更新されない

2022/5/3 Flutter エラー・バグ日記 

ローカルデータベース(DB)に「hive」を使用し、端末内に作成される「.hive」と「.lock」ファイルのバックアップ機能を実装した。

 

しかし、バックアップしたファイルを、外部からインポート(リストア)して「.hive」と「.lock」ファイルを上書き保存しても、画面表示されるデータが、インポート前(リストア前)のままで、更新されなかった

 

本記事はライトな日記思考で書いているので、詳細説明はしておらず、基本、テキストのみで画像とかは載せておりません。。m(_ _)m

解説記事ではないため、解決していない内容や、その時々の間違った解釈を述べてしまっている可能性が大いにありますので、何卒、ご了承ください。

 

実装方法の概略(問題解消前)は、以下のとおり。

 

  • 「path_provider」パッケージを利用し、「getApplicationDocumentsDirectory()」メソッドで、端末内のアプリ専用フォルダのDirectory型インスタンスを作成
  • 同フォルダ内にある「hive」のDBファイル(「####.hive」と「####.lock」。「sqflite」を使った場合の「####.db」に相当するファイル)のファイル名を使って「join(上記Directory型インスタンス.path, 上記ファイル名)」により、フルパス名を作成
  • 「File(フルパス名)」にて、インポート(リストア)先のFile型のインスタンスを作成
  • バックアップ先から読込んだバックアップファイルのデータを使って、「上記File型インスタンス.writeAsBytes(バックアップファイルのList<int>型)」メソッドで上書き保存

 

再描画を行う状態管理には「riverpod」を使用しており、インポート(リストア)後のDBから、描画用の変数に値を読込んだ上で、「StateNotifier」を通じて、変更通知を行っている。

 

過去に、ローカルDBとして「sqflite」を採用したアプリでは、この方法でうまく行ったのだが。。。

 

試しにアプリを再起動してみると、今度は、インポート(リストア)後のデータに画面表示が更新されていた。

 

従って、端末内のDBファイル自体は、きちんと更新されている。

 

「hive」の公式ドキュメントを改めてチェックするも、バックアップ・インポート(リストア)方法の情報は載っていない。

 

仕方なくググってみると、まさに同じ質問に対して「hive」作者の方が回答されているイシューがあった。

 

 

これによると、「hive」のファイルを上書きする前に、boxをcloseする必要がある模様。

 

そこで、以下のようにプロセスを修正したら、無事、インポート(リストア)後のデータが画面表示されるようになった(問題解消!)。

 

<問題解消時の実装方法>

  • 「path_provider」パッケージを利用し、「getApplicationDocumentsDirectory()」メソッドで、端末内のアプリ専用フォルダのDirectory型インスタンスを作成
  • 同フォルダ内にあるhiveのDBファイル(「####.hive」と「####.lock」。「sqflite」を使った場合の「####.db」に相当するファイル)のファイル名を使って「join(上記Directory型インスタンス.path, 上記ファイル名)」により、フルパス名を作成
  • 「File(フルパス名)」にて、インポート(リストア)先のFile型のインスタンスを作成
  • 【追加】「await boxのインスタンス.close()」メソッドにより、開いていたbox(DBファイル)を閉じる
  • バックアップ先から読込んだバックアップファイルを使って、「上記File型インスタンス.writeAsBytes(バックアップファイルのList<int>型)」メソッドで上書き保存
  • 【追加】「boxのインスタンス = await Hive.openBox(box名)」により、再びboxを開き、boxのインスタンスを再作成

 

なお、改めて「hive」のQ&Aを見てみると、

 

ボックスが不要になった場合は、ボックスを閉じる必要があります。キャッシュされたすべてのキーとボックスの値はメモリから削除され、アクティブな読み取りおよび書き込み操作がすべて終了すると、ボックスファイルが閉じられます。

https://docs.hivedb.dev/#/basics/boxes?id=close-box

 

という趣旨の記述があった。

 

「hive」は、DBからデータを読込むとき(「get」メソッド実行時)、非同期処理にする必要がなく、瞬時にデータ取得できる点が便利なのだが、恐らくメモリやキャッシュにデータを保存しているからなのだろう。

 

ただ、この影響で、boxをきちんと閉じないと、DBのファイル自体が上書きされても、メモリやキャッシュのデータが更新されず、再描画しても表示が更新されない、、という結果になったのでは?というのが自分なりの考察(違っているかも知れませんが、、、)。

 

\ Flutterの学習で役立ったコンテンツ・書籍 /

 

 

 


Dart入門 – Dartの要点をつかむためのクイックツアー
タイトルとURLをコピーしました