Overview of backend synchronization in drift
DialectAwareSqlType utility can be used.website·Indexed 34 days ago
https://drift.simonbinder.euA relational database library for Dart and Flutter, originally designed as a client-side wrapper for SQLite. It provides a fluent Dart API for queries, support for .drift SQL files, and compatibility with PostgreSQL, libSQL, and Turso. Features include auto-updating stream queries, type converters, modular code generation, and cross-platform support for mobile and desktop.
DialectAwareSqlType utility can be used.Drift is a reactive persistence library for relational data in Dart and Flutter applications. It acts as a layer on top of database libraries such as sqlite3 and sqflite to provide the following features:
List<Map<String, dynamic>>.select(users).watch())..createAllTables(), reducing the need for manual CREATE TABLE statements.sqlite3 is a synchronous C library, database operations on the main isolate can cause UI lag. The recommended way to avoid this is using NativeDatabase.createInBackground, which automatically spawns a background isolate managed by drift to execute SQL statements without requiring manual isolate setup.For every table defined in Drift, two classes are generated:
copyWith method.drift/native.dart library uses the sqlite3 package to execute queries. Starting from drift version 2.32.0, all native Dart and Flutter platforms are supported without additional setup or dependencies (e.g., sqlite3_flutter_libs is no longer required).MyDatabase class. Depending on your architecture, you can achieve this using a global variable, the provider package, GetX, or a dependency injection framework like get_it or kiwi.// Option 1: Vanilla Flutter (Global Variable)
late MyDatabase database;
void main() {
database = MyDatabase();
runApp(MyFlutterApp());
}
// Option 2: Using the provider package
void main() {
runApp(
Provider<MyDatabase>(
create: (context) => MyDatabase(),
child: MyFlutterApp(),
dispose: (context, db) => db.close(),
),
);
}
// Access via: Provider.of<MyDatabase>(context)
// Option 3: Using GetX
void main() {
Get.put(MyDatabase());
runApp(MyFlutterApp());
}
// Access via: Get.find<MyDatabase>().your_methodMigrator class is provided as a parameter in migration callbacks. It allows developers to create, drop, and alter schema elements. For operations not covered by the Migrator API, customStatement() can be used to run raw SQL.QueryInterceptor API allows developers to intercept and log details about database operations, such as execution time, success/failure status, and the specific SQL statements being run. This is more powerful than the basic logStatements option and can be used for performance monitoring, retrying failed statements, or sending statistics to external services.class LogInterceptor extends QueryInterceptor {
Future<T> _run<T>(
String description,
FutureOr<T> Function() operation,
) async {
final stopwatch = Stopwatch()..start();
print('Running $description');
try {
final result = await operation();
print(' => succeeded after ${stopwatch.elapsedMilliseconds}ms');
return result;
} on Object catch (e) {
print(' => failed after ${stopwatch.elapsedMilliseconds}ms ($e)');
rethrow;
}
}
@override
TransactionExecutor beginTransaction(QueryExecutor parent) {
print('begin');
return super.beginTransaction(parent);
}
@override
Future<void> commitTransaction(TransactionExecutor inner) {
return _run('commit', () => inner.send());
}
@override
Future<void> rollbackTransaction(TransactionExecutor inner) {
return _run('rollback', () => inner.rollback());
}
@override
Future<int> runInsert(
QueryExecutor executor,
String statement,
List<Object?> args,
) {
return _run('$statement with $args', () => executor.runInsert(statement, args));
}
@override
Future<List<Map<String, Object?>>> runSelect(
QueryExecutor executor,
String statement,
List<Object?> args,
) {
return _run('$statement with $args', () => executor.runSelect(statement, args));
}
// Similarly override runUpdate, runDelete, runCustom, and runBatched
}package:drift/native.dart on Android, very complex queries may trigger out-of-memory errors because the default temporary directory is unavailable. To resolve this, you must explicitly inform sqlite3 about the correct directory to store temporary data.For real-world use cases and complex architectures, refer to these community open-source projects using drift:
Drift provides two modes for storing DateTime values in SQL, configurable via the store_date_time_values_as_text build option:
INTEGER (seconds). When retrieved, Drift returns a non-UTC value; original UTC information is lost.DateTime.toIso8601String().Z are returned as UTC.+02:00) are parsed and converted via toLocal() to return a local value.datetime function behavior).Regardless of the mode, Drift's built-in date and time functions handle the conversion internally (using unixepoch for timestamps and julianday for text comparisons).