質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

Q&A

解決済

1回答

1144閲覧

データベース削除後に、"SqfliteDatabaseException (DatabaseException(database_closed))"とエラーが発生してしまう。

mako_0221

総合スコア87

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

0グッド

0クリップ

投稿2023/03/17 07:12

下記のコードのように、 DbHelper.instance.deleteDB();を一度実行した後、改めてからの配列が返ってくることを前提にDbHelper.instance.selectAllIcons()を実行しようとするとSqfliteDatabaseException(DatabaseException(database_closed))がthrowされてしまいます。

さらにFlutterをリロードして改めてDbHelper.instance.selectAllIcons()するとエラーが出力されずに、今度は期待通りからの配列を出力してくれます。したがって、リロード後であれば改めてdbはopen状態であり、実行されているのだと思います。

DbHelper.instance.deleteDB();直後にこのようなエラーが起こる理由と解決法にたどり着けず、アドバイスをいただければ幸いです。

宜しくお願い申し上げます。

version 情報:

  1. Flutter SDK

Flutter 3.3.1 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 4f9d92fbbd (6 months ago) • 2022-09-06 17:54:53 -0700
Engine • revision 3efdf03e73
Tools • Dart 2.18.0 • DevTools 2.15.0

  1. Package

sqflite: ^2.2.3

dart

1//main.dart 2onPressed: () async { 3 DbHelper.instance.deleteDB(); 4},

dart

1onPressed: () async { 2 List<IconList> lists = await DbHelper.instance.selectAllIcons(); 3 print(lists); 4},

dart

1//db_manager.dart 2import 'package:intl/intl.dart'; 3import 'package:path/path.dart'; 4import 'package:path_provider/path_provider.dart'; 5import 'package:sqflite/sqflite.dart'; 6 7const String columnId = '_id'; 8const String columnTitle = 'title'; 9const String columnSubTitle = 'subTitle'; 10const String columnIconPass = 'iconPass'; 11const String columnStatus = 'status'; 12const String columnMemo = 'memo'; 13const String columnCreatedAt = 'createdAt'; 14 15const List<String> columns = [ 16 columnId, 17 columnTitle, 18 columnSubTitle, 19 columnIconPass, 20 columnStatus, 21 columnMemo, 22 columnCreatedAt, 23]; 24 25class DbHelper { 26 DbHelper._createInstance(); 27 static DbHelper instance = 28 DbHelper._createInstance(); 29 static Database? _database; 30 31 Future<Database> get database async { 32 return _database ??= await _initDB(); 33 } 34 35 Future<Database> _initDB() async { 36 final dbDirectory = await getApplicationSupportDirectory(); 37 final dbFilePath = dbDirectory.path; 38 String path = join(await dbFilePath, 'cards.db'); 39 return await openDatabase( 40 path, 41 version: 1, 42 onCreate: _onCreate, 43 ); 44 } 45 46 void deleteDB() async{ 47 final dbDirectory = await getApplicationSupportDirectory(); 48 final dbFilePath = dbDirectory.path; 49 String path = join(await dbFilePath, 'cards.db'); 50 await deleteDatabase(path); 51 } 52 53 Future _onCreate(Database database, int version) async { 54 await database.execute(''' 55 CREATE TABLE icons( 56 _id INTEGER PRIMARY KEY AUTOINCREMENT, 57 title TEXT, 58 subTitle TEXT, 59 iconPass TEXT, 60 status INTEGER, 61 memo TEXT, 62 createdAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP 63 ) 64 '''); 65 } 66 67 Future<List<IconList>> selectAllIcons() async { 68 final db = await instance.database; 69 final iconListData = await db.query('icons'); 70 71 return iconListData 72 .map((json) => IconList.fromJson(json)) 73 .toList(); 74 } 75 76 Future insert(IconList iconList) async { 77 final db = await database; 78 return await db.insert( 79 'icons',//tablename 80 iconList.toJson() 81 ); 82 } 83 Future insertRows(List<IconList> rows) async{ 84 final db = await database; 85 Batch batch = db.batch(); 86 rows.forEach((row) => batch.insert('icons', row.toJson())); 87 await batch.commit(noResult: true); 88 } 89} 90 91class IconList { 92 final int? id; 93 final String title; 94 final String? subTitle; 95 final String iconPass; 96 final int status; 97 final String memo; 98 DateTime createdAt; 99 100 IconList( 101 { 102 this.id, 103 required this.title, 104 this.subTitle, 105 required this.iconPass, 106 required this.status, 107 required this.memo, 108 required this.createdAt 109 }); 110 111 IconList copy({ 112 int? id, 113 String? title, 114 String? subTitle, 115 String? iconPass, 116 int? status, 117 String? memo, 118 DateTime? createdAt, 119 }) => 120 IconList( 121 id: id ?? this.id, 122 title:title ?? this.title, 123 subTitle: subTitle ?? this.subTitle, 124 iconPass: iconPass ?? this.iconPass, 125 status: status ?? this.status, 126 memo: memo ?? this.memo, 127 createdAt: createdAt ?? this.createdAt, 128 ); 129 130 static IconList fromJson(Map<String, Object?> json) => IconList( 131 id: json[columnId] as int, 132 title: json[columnTitle] as String, 133 subTitle: json[columnSubTitle] as String?, 134 iconPass: json[columnIconPass] as String, 135 status: json[columnStatus] as int, 136 memo: json[columnMemo] as String, 137 createdAt: DateTime.parse(json[columnCreatedAt] as String), 138 ); 139 140 Map<String, Object?> toJson() => { 141 // columnId:id, 142 columnTitle:title, 143 columnSubTitle:subTitle, 144 columnIconPass: iconPass, 145 columnStatus: status, 146 columnMemo: memo, 147 columnCreatedAt: DateFormat('yyyy-MM-dd HH:mm:ss').format(createdAt), 148 }; 149} 150

dart

1//exception 2import 'package:sqflite/src/services_impl.dart'; 3import 'package:sqflite/src/sqflite_import.dart'; 4 5/// Wrap any exception to a [DatabaseException] 6Future<T> wrapDatabaseException<T>(Future<T> Function() action) async { 7 try { 8 final result = await action(); 9 return result; 10 } on PlatformException catch (e) { 11 if (e.code == sqliteErrorCode) { 12 throw SqfliteDatabaseException(e.message!, e.details); 13 //rethrow; 14 } else { 15 rethrow; 16 } 17 } 18}```

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

データベースを削除するとデータベースが閉じられるため再オープンが必要。
ということらしいです。

https://github.com/tekartik/sqflite/issues/406
上記issuesが参考になるのかな。

deleteDBの最後に_databaseをnullにして、database取り出し時に_initDBを呼び出せるようにしておくというのが正しい作法なのかな。

投稿2023/03/17 12:51

ta.fu

総合スコア1667

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mako_0221

2023/03/18 12:47

ta.fu様 ありがとうございます。 未だにFlutterの勉強段階から一歩抜け出せずにぜひお尋ねしたいことがあります。このような問題が発生したときに、どのようにあたりをつけたり、どのようなステップやアプローチでアドバイスに至っていらっしゃるのでしょうか? もうpackageの使い方の問題であるとあたりをつけていて、githubのissueでそれっぽいのがないかなとかを何よりもまず探しに行く等、私も早くそのようなアプローチを身につけようと試行錯誤はするのですが、あたりをつけられず、flutter自体やdartの問題なのか、色々範囲を広げてもなかなか答えに行きつかずというところでお尋ねした次第でございます。 何卒、宜しくお願い申し上げます。
ta.fu

2023/03/19 00:47

> このような問題が発生したときに、どのようにあたりをつけたり、どのようなステップやアプローチでアドバイスに至っていらっしゃるのでしょうか? 言葉にするのは難しい。 知識・経験から、としか言いようがない。 提示されたキーワードから問題点を類推するのだけど、そこが「知識・経験」から導き出したものということかな。 現在の言語やその環境などは、過去(10年前以上とか)習得したものと、設計思想的に大きな違いがないと思ってます。 なので、過去自分が出会ったあらゆるトラブルとその解決方法というのがあるのと、それをどうやって解決していったかという経験をあてはめて、解決していってるということになります。 あとDart/Flutterはソースコードが提示されてるので、手間と感じなければ、解決しやすいほうだと思いますけどね。
mako_0221

2023/03/19 01:36

ご回答有難うございます。 なるほど一朝一夕にはやはりなかなかいかない事は良く理解できました。 因みに今回のケースはご提示のgitのissuesに直接行かれましたか、それとも周辺をご確認されて結果行きつきましたか? 重ねて申し訳ございませんが、最後によければ聞かせてください。 宜しくお願い申し上げます。
ta.fu

2023/03/19 01:44

今回の件でいうと、例外で出ているdatabase_closedと関連するであろうAPI deleteDatabaseでググると、stackoverflowとgithubのissuesがトップに出てきます。 それぞれのトップを見て、github側が合致しただけです。 なので、問題の原因と目される情報を得るまで10分もかからなかったと思います。
mako_0221

2023/03/19 08:30

よく分かりました! 有難うございます。深謝でございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問