我目前正在开发一个桌面应用程序,可以直接与
postgres
数据库进行通信。由于插入需要数十分钟才能完成并冻结 UI,因此我在网上读到,通过使用隔离或计算,此过程可以变成“多线程”。不幸的是,我在使用计算时收到错误,指出连接无法在隔离中传递。 import 'package:excel/excel.dart';
import 'package:flutter/foundation.dart';
import 'package:postgres/postgres.dart';
import '../ConnectionRelated/PostgresConnectionHelper.dart';
import '../ConnectionRelated/RawQueryRunner.dart';
// A class to hold isolate parameters
class TaskParams {
final Connection connection;
final Sheet table;
final int temperatureId;
final String temperatureDataArray;
TaskParams(this.connection, this.table, this.temperatureId,
this.temperatureDataArray);
}
class TemperatureDataInserter2 {
static void test_function(TaskParams taskParams) async {
//
// Connection connection, Sheet table,
// int temperatureId, String temperatureDataArray
Sheet? table= taskParams.table;
Connection connection = taskParams.connection;
int temperatureId = taskParams.temperatureId;
String temperatureDataArray = taskParams.temperatureDataArray;
// Fetch Fluoresence data from column 2 until 49, column indices 1 to 48
for (int column = 1; column < table.rows[0].length; column++) {
List<double> fluorescenceData = [];
for (int i = 1; i < table.rows.length; i++) {
var cellValue = table.rows[i][column]?.value;
// Check the type of cell value and convert it to double
if (cellValue is double) {
fluorescenceData.add(cellValue);
} else if (cellValue is int) {
fluorescenceData.add(cellValue.toDouble());
}
}
// Convert the Fluorescence data list to a PostgreSQL array format
String fluorescenceDataArray = fluorescenceData.join(',');
int temperatureIdOffset = temperatureId + column;
String insertQuery = """
INSERT INTO public.temperature_data (dna_test_id,
temperature_celsius_array,
fluorescence_array)
VALUES ($temperatureIdOffset,
ARRAY[$temperatureDataArray]::double precision[],
ARRAY[$fluorescenceDataArray]::double precision[]);
""";
await new RawQueryRunner().run(connection, insertQuery);
// final result = await compute(fibonacci, 40);
// print('Fibonacci result: $result');
}
}
Future<void> Execute(Excel excel) async {
// if (!excel.tables.containsKey(sheetName)) {
// print('Sheet "$sheetName" does not exist');
// return;
// }
// final table = excel.tables[sheetName];
final table = excel.tables["High Resolu…Melt Target Data"];
if (table == null) {
print('Table for sheet "$table" is null');
return;
} else {
print('Table sheet name is: "$table"');
}
// // TableRowPrinter().run(table);
// var table2 = excel.tables["Samples"]!;
// SamplePrinter().run(table2);
Connection? connection = await PostgresConnectionHelper().Connect();
if (connection != null) {
String sql = """
INSERT INTO public.dna_test (id)
SELECT nextval('test_results_id_seq')
FROM generate_series(1, 48);
""";
// Adds 48 empty dna_tests with (the dna_test.id is auto incremental)
await new RawQueryRunner().run(connection, sql);
// Get the max id after inserting the new records
String getMaxIdSql = "SELECT MAX(id) FROM public.dna_test";
List<List<dynamic>> result = await connection.execute(getMaxIdSql);
int maxId = result.first.first;
int temperatureId = maxId - 48;
// First column is temperatureData which is
// second row first column (index 1,0)
List<double> temperatureData = [];
for (int i = 1; i < table.rows.length; i++) {
var cellValue = table.rows[i][0]?.value;
// Check the type of cell value and convert it to double
if (cellValue is double) {
temperatureData.add(cellValue);
} else if (cellValue is int) {
temperatureData.add(cellValue.toDouble());
}
}
// Declaring and assigning the
// maxTemperatureValue and minTemperatureValue
var maxTemperatureValue = temperatureData[0];
var minTemperatureValue = temperatureData[0];
for (var i = 0; i < temperatureData.length; i++) {
// Checking for largest value in the list
if (temperatureData[i] > maxTemperatureValue) {
maxTemperatureValue = temperatureData[i];
}
// Checking for smallest value in the list
if (temperatureData[i] < minTemperatureValue) {
minTemperatureValue = temperatureData[i];
}
}
List<double> temperatureDataMinMaxRange = [];
// Round the min and max Values on the 2 digits
var roundedMinTemperatureValue =
(minTemperatureValue * 100).roundToDouble() / 100;
var roundedMaxTemperatureValue =
(maxTemperatureValue * 100).roundToDouble() / 100;
// Printing the values
print("Smallest rounded value in the list : $roundedMinTemperatureValue");
print("Largest rounded value in the list : $roundedMaxTemperatureValue");
temperatureDataMinMaxRange.add(roundedMinTemperatureValue);
temperatureDataMinMaxRange.add(roundedMaxTemperatureValue);
// Convert the temperature data list to a PostgreSQL array format
String temperatureDataArray = temperatureDataMinMaxRange.join(',');
//The original code which must become multi threaded
// Fetch Fluoresence data from column 2 until 49, column indices 1 to 48
for (int column = 1; column < table.rows[0].length; column++) {
List<double> fluorescenceData = [];
for (int i = 1; i < table.rows.length; i++) {
var cellValue = table.rows[i][column]?.value;
// Check the type of cell value and convert it to double
if (cellValue is double) {
fluorescenceData.add(cellValue);
} else if (cellValue is int) {
fluorescenceData.add(cellValue.toDouble());
}
}
// Convert the Fluorescence data list to a PostgreSQL array format
String fluorescenceDataArray = fluorescenceData.join(',');
int temperatureIdOffset = temperatureId + column;
String insertQuery = """
INSERT INTO public.temperature_data (dna_test_id,
temperature_celsius_array,
fluorescence_array)
VALUES ($temperatureIdOffset,
ARRAY[$temperatureDataArray]::double precision[],
ARRAY[$fluorescenceDataArray]::double precision[]);
""";
await new RawQueryRunner().run(connection, insertQuery);
}
// The code where isolate crashes because it can't accept connection
await compute(test_function,
TaskParams(connection, table, temperatureId, temperatureDataArray));
}
}
}
设法通过在 test_function 内创建一个新连接来修复它,如下所示
Connection? connection = await PostgresConnectionHelper().Connect();
但是我有兴趣知道是否可能以及将连接作为参数传递的良好实践。