web-dev-qa-db-fra.com

Sugar ORM ne crée tout simplement pas de tables

Je travaille sur un projet de bibliothèque autonome qui nécessite la persistance d'un modèle simple. Voici à quoi ressemble mon SugarRecord:

/**
 *  Keeping track of previously received messages by ID
 */

public class MessageRequestIdModel extends SugarRecord {

    protected String messageRequestId;

    public MessageRequestIdModel() {

    }

    public MessageRequestIdModel(String messageRequestId) {
        this.messageRequestId = messageRequestId;
    }

    public String getMessageRequestId() {
        return this.messageRequestId;
    }

    public static boolean exists(String id) {
        return MessageRequestIdModel.find(
                MessageRequestIdModel.class,
                "messageRequestId = ?",
                id
        ).size() != 0;
    }
}

Dans une classe de référentiel, j'essaie de la persister en appelant cette méthode:

@Override
public void save(MessageRequestId messageRequestId) {
    new MessageRequestIdModel(messageRequestId.getId()).save();
}

J'essaie maintenant de tester cela en utilisant un Android.test.InstrumentationTestCase Où je passe un Context à Sugar comme ceci:

SugarContext.init(getInstrumentation().getContext());

Cela se traduit par cette erreur lorsque j'exécute le test: (tronquer pour garder cette question une lecture succincte)

Android.database.sqlite.SQLiteException: no such table: MESSAGE_REQUEST_ID_MODEL (code 1): , while compiling: INSERT or REPLACE...

Dépannage que j'ai déjà tenté:

  • Conserver un manifeste différent pour le package de test afin de transmettre le nom du package .test À SugarORM. Pas de changement de comportement
  • Ajouter une MessageRequestIdModel.findById(MessageRequestIdModel.class, (long) 1); comme dans les autres SO publications. Modifie l'erreur en elle-même (Afficher la trace complète de la pile ici au cas où cela aiderait):

    Android.database.sqlite.SQLiteException: no such table: MESSAGE_REQUEST_ID_MODEL (code 1): , while compiling: SELECT * FROM MESSAGE_REQUEST_ID_MODEL WHERE id=? LIMIT 1
    
    at Android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
    at Android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.Java:889)
    at Android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.Java:500)
    at Android.database.sqlite.SQLiteSession.prepare(SQLiteSession.Java:588)
    at Android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.Java:58)
    at Android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.Java:37)
    at Android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.Java:44)
    at Android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.Java:1316)
    at Android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.Java:1163)
    at Android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.Java:1034)
    at Android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.Java:1240)
    at com.orm.SugarRecord.find(SugarRecord.Java:192)
    at com.orm.SugarRecord.findById(SugarRecord.Java:102)
    at pm.tin.apprise.entities.message_request_ids.MessageRequestIdModelRepository.save(MessageRequestIdModelRepository.Java:19)
    
  • J'ai essayé de supprimer toutes les config Sugar ORM du Manifeste comme le suggèrent de nombreuses personnes - cela ne change rien

  • J'ai essayé de créer un module Sample App et j'ai essayé de l'exécuter en tant que cas de test pour cette application, au cas où les applications autonomes n'obtiendraient pas les bonnes ressources sur l'émulateur/l'appareil (j'ai testé sur les deux)

  • J'ai essayé d'incrémenter le nombre VERSION pour la base de données

  • J'ai essayé de passer à un ActivityTestCase et d'utiliser getActivity().getApplicationContext(). Cela échoue essentiellement avec une erreur qui suggère que ce contexte est incomplet pour pouvoir configurer SQLite

Comme vous pouvez le voir, j'ai poussé fort sur ce rocher toute la nuit, mais à ce stade, il semble que Sisyphean et je n'ai absolument aucune piste pour ma prochaine tentative de débogage autre que d'utiliser un ORM différent de Sugar (ce qui ne fait pas vraiment semblent être le problème). Il n'y a rien de plus émasculant que de ne pas pouvoir exécuter SQLite dans un cas de test et je crie à la conscience du programmeur sacré en vous pour obtenir de l'aide: - '(

18
Angad

Cela devrait résoudre ce problème de manière concluante pour toutes les personnes qui luttent pour que Sugar ORM fonctionne immédiatement - utilisez le système de gestion des versions SQL pour déclencher manuellement la création SQL.

Dans le cas d'utilisation ci-dessus, voici comment procéder:

1.) Remplacez la version DB de Sugar ORM config par un nouveau numéro (par exemple N) de sorte qu'il soit supérieur à la version actuelle [~ # ~] ou [~ # ~] = changer le nom de la base de données

2.) Créez un fichier ModuleName/src/main/assets/sugar_upgrades/<N>.sql Avec votre SQL; montrant le mien, au cas où cela aiderait:

DROP TABLE MESSAGE_REQUEST_ID_MODEL;

CRÉER LA TABLE MESSAGE_REQUEST_ID_MODEL (ID INTEGER PRIMARY KEY AUTOINCREMENT, MESSAGE_REQUEST_ID CHAR (128));

Cela forcera Sugar à déclencher votre SQL pour créer la table pour vous (quoique manuellement).

Notes supplémentaires

  • Cette section du manuel Sugar ORM est l'inspiration derrière ce correctif (quoique hacky): http://satyan.github.io/sugar/migration.html
  • J'ai commenté le nom du package dans Sugar config
  • Sugar fonctionne avec un contexte d'application d'instrumentation. Dans une classe de base de InstrumentationTestCase, faites simplement SugarContext.init(getInstrumentation().getTargetContext()) comme indiqué dans la question d'origine
8
Angad

Ce problème a été observé dans les versions Android Studio 2.x.x-beta (notamment 2.0.0-beta6) et a sa cause première dans la fonction 'Instant Run'.

J'imagine que cela peut être corrigé sous peu, mais pour que cela fonctionne entre-temps, vous devez désactiver la fonctionnalité dans le menu suivant

File | Settings | Build, Execution, Deployment | Instant Run

Le nettoyage puis la création de l'application devraient résoudre ces problèmes.

Vous pouvez voir le rapport de bogue Sugar associé ici .

23
Ed George

votre problème peut être la création d'une classe ...

public class MessageRequestIdModel extends SugarRecord<MessageRequestIdModel> {

    protected String messageRequestId;

    public MessageRequestIdModel() {

    }

    public MessageRequestIdModel(String messageRequestId) {
        this.messageRequestId = messageRequestId;
    }

    public String getMessageRequestId() {
        return this.messageRequestId;
    }

    public static boolean exists(String id) {
        return MessageRequestIdModel.find(
                MessageRequestIdModel.class,
                "messageRequestId = ?",
                id
        ).size() != 0;
    }
}

veuillez revérifier avec mon code.

1
rockstar