Flutter Sqflite database DatabaseException no such table Is Occur - database

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: DatabaseException(no such table: MST_University (code 1 SQLITE_ERROR): , while compiling: SELECT * FROM MST_University) sql 'SELECT * FROM MST_University' args []
import 'dart:developer';
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
class DataBaseHelper {
static var _database;
DataBaseHelper._privateConstructor();
static final DataBaseHelper instance = DataBaseHelper._privateConstructor();
Future<Database> get database async {
if (_database != null) {
log("Database new is not creatred and retuned ");
return _database;
}
// Call init Databasee method for New Database Creation
log("new Database is create");
_database = await _initDatabase();
return _database;
}
Future<Database> _initDatabase() async {
Directory appDocDir = await getApplicationDocumentsDirectory();
log("new dAta");
String databasePath = join(appDocDir.path, 'pharmacy2.db');
return await openDatabase(
databasePath,
version: 2,
);
}
Future<void> copyPasteAssetFileToRoot() async {
Directory documentsDirectory = await getApplicationDocumentsDirectory();
log("assets database is loading");
String path = join(documentsDirectory.path, "pharmacy2.db");
if (FileSystemEntity.typeSync(path) == FileSystemEntityType.notFound) {
ByteData data =
await rootBundle.load(join('assests/database', 'pharmacy2.db'));
List<int> bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await File(path).writeAsBytes(bytes);
}
}
Future<void> getAllUniversity() async {
Database db = await instance.database;
var result = await db.query("MST_University");
log(result.toString());
}
}
I try a privet constructor for single instance and also load database from a assets

I cannot see where you call copyPasteAssetFileToRoot, so maybe never?
assests/database looks very much like a typo.
Even if that all is correct, the database you open has no such table.
Why don't you set a few breakpoints in your debugger and find out what steps work and which don't. Whether you path is set correctly and your file gets copied or not. Whether you open the correct file. Whether that file actually has such a table.

Related

Unhandled Exception: LateInitializationError: Field '_database#91313886' has not been initialized

I'm a beginner in flutter
I want to link the db file that I have.
There is an error related to initialization, but I don't know what the problem is
2022-02-16 17:47:47.530 20199-20218/com.example.flower_sunset_2 E/flutter: [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: LateInitializationError: Field '_database#91313886' has not been initialized.
#0 DatabaseProvider._database (package:flower_sunset_2/database.dart)
#1 DatabaseProvider.database (package:flower_sunset_2/database.dart:19:9)
class DatabaseProvider {
static final DatabaseProvider provider = DatabaseProvider();
late Database _database;
Future<Database> get database async {
if (_database != null) return _database;
_database = await createDatabase();
return _database;
}
createDatabase() async {
// Directory docsDir = await getApplicationDocumentsDirectory();
// String path = join(docsDir.path, "repo_db_senior.db");
var databasePath = await getDatabasesPath();
var path = join(databasePath, "repo_db_senior.db");
// Check if the database exists
var exists = await databaseExists(path);
print("database start");
if(!exists) {
// Should happen only the first time you launch your application
print("Creating new copy from asset");
// Make sure the parent directory exists
try {
await Directory(dirname(path)).create(recursive: true);
} catch (_) {}
// Copy from asset
ByteData data = await rootBundle.load(join('repo', 'db', 'senior.db'));
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
// Write and flush the bytes written
await File(path).writeAsBytes(bytes, flush: true);
}
else {
print("Opening existing database");
}
var database = await openDatabase(path, readOnly: true);
// var database = await openDatabase(path, version: 1, onCreate: initDB, onUpgrade: onUpgrade);
return database;
}
}
pubspec.yaml
assets:
- repo/db/senior.db
your database file names are not matching. In pubspec.yaml file you have it as 'senior.db' while in your code you are looking for 'repo_db_senior.db'.

Flutter sqflite insert does not store full data fetched using http get

I'm new to Flutter
my app fetches json records from the http get method and stores the data to database.
very thing works fine json returns around 149 rows but app only inserts 101 row in the table there is no error or anything.
Firstly I thought that http only response with only 101 records but on testing http get prints all the 149 record but on insert to database it only insert's only 101 only
if I parse 80 or 90 records it all gets inserted but even 102 records only insert's 101
even tried Future Delay for 10s but it gets break at 101 and then waits till the delay in competed
APIProvider
class ApiProvider {
Future<List<NewProduct>?> getPro() async {
Response response = await Dio().get(Info.productUrl);
var res = response.data;
print("PRODUCT LENGTH-" + res.length);
(res as List).map((product) {
DatabaseHelper.db.insertProduct(NewProduct.fromJson(product));
}).toList();
}
}
Database Helper Class
import 'dart:io';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:models/newProductHome.dart';
import 'package:sqflite/sqflite.dart';
class DatabaseHelper {
static final _dbName = 'sawanDB.db';
static final _dbVersion = 1;
static Database? _database;
static final DatabaseHelper db = DatabaseHelper._();
DatabaseHelper._();
Future<Database> get database async {
if (_database != null) return _database!;
_database = await _initiateDatabase();
return _database!;
}
_initiateDatabase() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = join(directory.path, _dbName);
return await openDatabase(path, version: _dbVersion, onCreate: _onCreate);
}
Future _onCreate(Database db, int version) async {
await db.execute('DROP TABLE If EXISTS SA_PRO_MASTER');
await db.execute('''
CREATE TABLE SA_PRO_MASTER(
sa_proid TEXT,
sa_proname TEXT NOT NULL,
sa_pcat TEXT NOT NULL,
sa_pscat TEXT NOT NULL,
sa_pbrand TEXT NOT NULL,
sa_pro_code TEXT,
sa_pro_capacity TEXT,
sa_pro_status TEXT,
sa_pro_mtitle TEXT,
sa_pro_mkey TEXT,
sa_pro_mdesc TEXT,
sa_pro_date DATE,
sa_pro_mainImg TEXT,
sa_pro_ishome TEXT,
sa_pro_desc TEXT,
sa_pro_new TEXT,
sa_pro_type TEXT
)
''');
print("DB TABLE SA_PRO_MASTER CREATED");
}
insertProduct(NewProduct listPro) async {
final db = await database;
final res = await db.insert('SA_PRO_MASTER', listPro.toJson());
//print("INSERT RES - " + res.toString());
return res;
}
Future<int> deleteAllProduct() async {
final db = await database;
final res = await db.rawDelete('DELETE FROM SA_PRO_MASTER');
return res;
}
}
Main where it loads Data while opening the app
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(backgroundHandler);
DatabaseHelper.db.database;
if (await InternetConnectionChecker().hasConnection) {
print("INTERNERT AVAILABLE");
DatabaseHelper.db.deleteAllProduct();
await apiProvider.getAllProducts();
await Future.delayed(const Duration(seconds: 1));
runApp(MyApp());
} else {
print("NO INTERNET");
runApp(NoConn());
}
//await Future.delayed(const Duration(seconds: 1));
}

Sqflite Database exception no such table in flutter

I have loaded json data in a list of objects. Whenever I try to insert data into a table my console says "Unhandled Exception: DatabaseException(no such table: Album (code 1 SQLITE_ERROR): , while compiling: INSERT OR REPLACE INTO Album...." . I know before inserting data I have to create database and table. I have done that in my code. But for some unknown reason the table doesn't get build. Here is my database helper class -
class DatabaseHelper {
static final _dbName = "myDatabase.db";
static final _dbVersion = 1;
static final _tableAlbum = "Album";
static final columnAlbum = '_fetched_album';
DatabaseHelper._privateConstructor();
static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
static Database? _database;
Future<Database?> get database async {
if (_database == null) {
print("instance.db null");
_database ??= await _initiateDatabase();
return _database;
}else{
print("instance.db not null");
return _database; }
}
Future<Database> _initiateDatabase() async {
String directory = await getDatabasesPath();
String path = join(directory, _dbName);
return await openDatabase(
path,
version: _dbVersion,
onCreate:(Database db,int version) async {
await db.execute('''
CREATE TABLE $_tableAlbum (
$columnAlbum TEXT
)''');
},
);
}
Future<int?> insertAlbum(ModelAlbum list) async {
Database? db = await instance.database;
return await db?.insert(
_tableAlbum,list.toMap(),conflictAlgorithm: ConflictAlgorithm.replace);
}
Future<int?> insertPhoto(ModelPhoto list) async {
Database? db = await instance.database;
return await db?.insert(
_tablePhoto,list.toMap(),conflictAlgorithm: ConflictAlgorithm.replace);
}
Future<List<Map<String, dynamic>>> queryAlbum() async {
Database? db = await instance.database;
return await db!.query(_tableAlbum);
}
Future<List<Map<String, dynamic>>> queryPhoto() async {
Database? db = await instance.database;
return await db!.query(_tableAlbum);
}
Future<List<ModelAlbum>> retrieveAlbum() async {
final Database? db = await database;
final List<Map> maps = await db!.query(_tableAlbum);
return List.generate(maps.length, (i) {
return ModelAlbum(
id: maps[i]['id'],
title: maps[i]['title'],
userId: maps[i]['userId'],
);
});
}
Future<List<ModelPhoto>> retrievePhoto() async {
final Database? db = await database;
final List<Map> maps = await db!.query(_tablePhoto);
return List.generate(maps.length, (i) {
return ModelPhoto(
albumId: maps[i]['albumId'],
thumbnailUrl: maps[i]['thumbnailUrl'],
url: maps[i]['url'],
id: maps[i]['id'],
title: maps[i]['title'],
);
});
}
}
Whenever Database.instance.insert(object); gets called the database and table should be automatically created. But it doesn't.
You are referring to static fields from instance methods. this may a problem try removing static keyword from the fields as,
final _dbName = "myDatabase.db";
final _dbVersion = 1;
final _tableAlbum = "Album";
final columnAlbum = '_fetched_album';

Access SQLite DB in Flutter

I am creating a DB in my native Android code using SQLite. Now I want to access the same DB in Flutter, below is my code:
class DatabaseHelper
{
static final _dbName="abc.db";
static final _dbVersion=1;
DatabaseHelper._privateConstructor();
static final DatabaseHelper instance=DatabaseHelper._privateConstructor();
static Database _database;
Future<Database> get datatbase async
{
if(_database!=null) {
print(_database.path);
return _database;
}/* */
}
Future<List<Map<String,dynamic>>> getAllLogs()async
{
final Database db= await instance.datatbase;
return await db.query("calls_history");
}
Whenever I call getAllLogs in my Flutter Widget I get the error: calls_history doesn't exist.
However, when I run the same query on native, it returns me the result
On flutter side you can use sqflite plugin, this plugin is built on top of native SQLite so you don't need to do anything special just refer to the same database name in flutter.
In one of my flutter projects I have used native android to code to receive messages and save them in SQLite database and on the flutter side I have used same database using sqflite to display the contents of database.
Here is the flutter side code
import 'dart:async';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
class SMSHelper {
Database? db;
Future open() async {
db = await openDatabase(
// by default path for database on the device is /data/data/<your app id>/databases/<your database file.db>
join(await getDatabasesPath(), 'ofs_sms_database.db'),
version: 1, onCreate: (Database db, int version) async {
await db.execute(
"CREATE TABLE smslogs(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, employeeID TEXT, department TEXT, module TEXT, message TEXT, safeUnsafeStatus TEXT, contactNo Text, dateTime INTEGER)");
});
}
Future<void> insertSMS(SMSLog smsLog) async {
await db?.insert(
'smslogs',
smsLog.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
Future<List<SMSLog>> getAllSMS() async {
if (db == null) {
open();
}
final List<Map<String, dynamic>>? maps = await db?.query('smslogs');
// Convert the List<Map<String, dynamic> into a List<Dog>.
if (maps != null) {
return List.generate(maps.length, (i) {
return SMSLog(
employeeID: maps[i]['employeeID'],
department: maps[i]['department'],
module: maps[i]['module'],
message: maps[i]['message'],
safeUnsafeStatus: maps[i]['safeUnsafeStatus'],
contactNo: maps[i]['contactNo'],
dateTime: maps[i]['dateTime']);
});
} else {
return [];
}
}
Future close() async => db?.close();
}
class SMSLog {
final String employeeID;
final String department;
final String module;
final String message;
final String safeUnsafeStatus;
final String contactNo;
final int dateTime;
SMSLog(
{required this.employeeID,
required this.department,
required this.module,
required this.message,
required this.safeUnsafeStatus,
required this.contactNo,
required this.dateTime});
Map<String, dynamic> toMap() {
return {
'employeeID': employeeID,
'department': department,
'module': module,
'message': message,
'safeUnsafeStatus': safeUnsafeStatus,
'contactNo': contactNo,
'dateTime': dateTime
};
}
}

How to create multiple table in Sqlite database at different times in Flutter

So Initially I created a table named "TABLE" in the database. I wanted to add another table. So I added another query to create a table. However I get an error saying "TABLE1 does not exist" when I run the app.
I do feel like there is a flaw in my code. I think the _onCreate() method will only be called the first time I run the app. So any code I add on _onCreate() method afterwards will not run. Any help will be appreciated.
class DBHelper {
static Database _db;
static const String DB_NAME = 'employeeDB';
static const String ID = 'id';
static const String NAME = 'name';
static const String TABLE = 'Employee';
static const String ID1 = 'id1';
static const String NAME1 = 'name1';
static const String TABLE1 = 'Employee1';
Future<Database> get db async {
if (_db != null) {
return _db;
}
_db = await initDb();
return _db;
}
initDb() async {
io.Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, DB_NAME);
var db = await openDatabase(path, version: 1, onCreate: _onCreate);
return db;
}
_onCreate(Database db, int version) async {
await db.execute("CREATE TABLE $TABLE ($ID INTEGER PRIMARY KEY,$NAME TEXT)");
await db.execute("CREATE TABLE $TABLE1 ($ID1 INTEGER PRIMARY KEY,$NAME1 TEXT)");
}
Future<Employee> save(Employee employee) async {
var dbClient = await db;
employee.id = await dbClient.insert(TABLE, employee.toMap());
return employee;
}
Future<Employee1> saveEmp1(Employee1 employee) async {
var dbClient = await db;
employee.id = await dbClient.insert(TABLE1, employee.toMap());
return employee;
}
Future<List<Employee>> getEmployees() async {
var dbClient = await db;
List<Map> maps = await dbClient.query(TABLE, columns: [ID, NAME]);
List<Employee> employees = [];
if (maps.length > 0) {
for (int i = 0; i < maps.length; i++) {
employees.add(Employee.fromMap(maps[i]));
}
}
return employees;
}
Future<List<Employee1>> getEmployees1() async {
var dbClient = await db;
List<Map> maps = await dbClient.query(TABLE1, columns: [ID1,
NAME1]);
List<Employee1> employees = [];
if (maps.length > 0) {
for (int i = 0; i < maps.length; i++) {
employees.add(Employee.fromMap(maps[i]));
}
}
return employees;
}
}
The first time run this app and initDb() in emulator, the db file employeeDB has created.
and it will not be created again
For only test app execution,
you can change
String DB_NAME = 'employeeDB'
to another name
String DB_NAME = 'employeeDB1'
or you can uninstall this app from Emulator first then run it again.
source code snippet of https://github.com/tekartik/sqflite/blob/master/sqflite/lib/sqlite_api.dart
/// Called when the database is created.
OnDatabaseCreateFn onCreate;
For schema migration, you can use OnUpgrade, detail reference https://efthymis.com/migrating-a-mobile-database-in-flutter-sqlite/
code snippet
await openDatabase(path,
version: 1,
onCreate: (Database db, int version) async {
await db.execute(initialSchema));
},
onUpgrade: (Database db, int oldVersion, int newVersion) async {
await db.execute(migrationScript));
});
You have to create migrations and run them against your existing database using the onUpgrade handler. Basically you need to check the existing database version and upgrade if the version is smaller than the migration number.
You can check out the detail steps/code tutorial here.
I needed to create more than just multiple tables; but multiple database. I have since developed a dart package; sqlite_at_runtime that stretches to as far as creating all these entities at run time.
Below is an example code that creates three tables with similar attributes.
await Sqlartime.tableCreate(['sample1','sample2','sample3'],['name TEXT','age INTEGER','temp REAL']);

Resources