Как вставить объекты и списки POJO в SQFlite - PullRequest
0 голосов
/ 24 апреля 2020

Я пытаюсь сохранить данные из API в sqflite, но мне нужно вставить Объекты и Списки , однако во время процесса появляется эта ошибка:

ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: DatabaseException(java.lang.String cannot be cast to java.lang.Integer) sql 'INSERT INTO articleTable (id, created_on, title, summary, details, tags, featured_image, author, category) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)' args [21, 2020-04-14 04:04:57, Singer Jose ...}]

Это класс Article класса:

@JsonSerializable(explicitToJson: true)
class Article {
  Article(this.id, this.created_on, this.title, this.details,
      this.featured_image, this.author, this.category, this.summary, this.tags);

  int id;
  String created_on;
  String title;
  String summary;
  String details;
  List<String> tags;
  String featured_image;
  Author author;
  Category category;

  factory Article.fromJson(Map<String, dynamic> json) =>
      _$ArticleFromJson(json);

  Map<String, dynamic> toJson() => _$ArticleToJson(this);
}

Автоматически сгенерированный файл для Article класса модели:

/ GENERATED CODE - DO NOT MODIFY BY HAND

part of 'article.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

Article _$ArticleFromJson(Map<String, dynamic> json) {
  return Article(
    json['id'] as int,
    json['created_on'] as String,
    json['title'] as String,
    json['details'] as String,
    json['featured_image'] as String,
    json['author'] == null
        ? null
        : Author.fromJson(json['author'] as Map<String, dynamic>),
    json['category'] == null
        ? null
        : Category.fromJson(json['category'] as Map<String, dynamic>),
    json['summary'] as String,
    (json['tags'] as List)?.map((e) => e as String)?.toList(),
  );
}

Map<String, dynamic> _$ArticleToJson(Article instance) => <String, dynamic>{
      'id': instance.id,
      'created_on': instance.created_on,
      'title': instance.title,
      'summary': instance.summary,
      'details': instance.details,
      'tags': instance.tags,
      'featured_image': instance.featured_image,
      'author': instance.author?.toJson(),
      'category': instance.category?.toJson(),
    };

Здесь я делаю Sqflite вставку:

class ArticleApiProvider {
  Future<List<Article>> fetchArticles() async {
    final response =
        await http.get('https://api.xyxyxyxy');

    if (response.statusCode == 200) {
      List jsonResponse = jsonDecode(response.body);
      return jsonResponse.map((article) {
        articleBloc.addArticles(Article.fromJson(article));
      }).toList();
    } else {
      throw Exception('Failed to retrieve articles');
    }
  }
}

Мой Blo c Класс:

class ArticleBloc {
  final _repository = Repository();
  final _articleFetcher = PublishSubject<List<Article>>();

  Stream<List<Article>> get allArticles => _articleFetcher.stream;

  fetchArticles() async {
    List<Article> articles = await _repository.fetchArticles();
    _articleFetcher.sink.add(articles);
  }

   getArticlesCached() async {
    // sink is a way of adding data reactively to the stream
    // by registering a new event

    _articleFetcher.sink.add(await _repository.getAllArticles());
  }

   void addArticles(Article article) async {
    await _repository.insertArticle(article);
  }

  dispose() {
    _articleFetcher.close();
  }
}

final articleBloc = ArticleBloc();

Это DatabaseProvider класс

final articlesTable = "articleTable";

class DatabaseProvider {
  static final DatabaseProvider dbProvider = DatabaseProvider();
   Database _database;

  String id = "id";
  String createdOn = "created_on";
  String title = "title";
  String summary = "summary";
  String details = "details";
  String featuredImage = "featured_image";
  String author = "author";
  String category = "category";
  String tags = "tags";

  Future<Database> get database async {
    if (_database != null) return _database;
    _database = await createDatabase();
    return _database;
  }

  createDatabase() async {
    Directory documentsDirectory = await getApplicationDocumentsDirectory();

    // NewVision.db is our database instance name
    String path = join(documentsDirectory.path, "NewVision.db");

    var database = await openDatabase(path,
        version: 1, onCreate: initDB, onUpgrade: onUpgrade);

    return database;
  }

  void initDB(Database db, int version) async {
    await db.execute(
        'CREATE TABLE $articlesTable($id INTEGER PRIMARY KEY AUTOINCREMENT, $createdOn TEXT,  $title TEXT ,'
        ' $summary TEXT , $details TEXT , '
        '$tags TEXT,  $featuredImage TEXT , $author TEXT , $category TEXT )');
  }

  void onUpgrade(Database db, int oldVersion, int newVersion) {
    if (newVersion > oldVersion) {}
  }
}

String join(String path, String s) {
  return path + s;
}

Остальные файлы соответствуют архитектуре Blo c, чтобы уточнить вопрос, я думаю, что из того, что я предоставил, я могу получить некоторую помощь.

Буду благодарен за вашу помощь.

1 Ответ

1 голос
/ 25 апреля 2020

Спасибо за подробный отчет. Я предполагаю, что ошибка произошла из вашей tags собственности. Список строк не поддерживается в SQLite. sqflite поддерживает List of int по причине совместимости (для больших двоичных объектов, но Uint8List, вероятно, будет единственным поддерживаемым типом в будущем), поэтому из-за этого может произойти ошибка приведения.

Вы должны попытаться закодировать свои теги (json или через запятую) перед выполнением другого исследования.

Эта проблема также относится к полям author и category. Вы должны сгладить свою модель. См. Раздел справки по поддерживаемым типам: https://github.com/tekartik/sqflite/blob/master/sqflite/doc/supported_types.md

В основном поддерживаются только int, double, String и Uint8List (blob). К сожалению, вы должны преобразовать свой внутренний Список и Карту, json являясь одним из решений.

Но я согласен с тем, что сообщенная ошибка не помогает найти проблему, которую, безусловно, можно улучшить ...

...