web-dev-qa-db-ja.com

Sugar ORMはテーブルを作成しません

単純なモデルを永続化する必要があるスタンドアロンライブラリプロジェクトに取り組んでいます。 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;
    }
}
_

リポジトリクラスでは、次のメソッドを呼び出して永続化しようとしています。

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

_Android.test.InstrumentationTestCase_を使用してこれをテストしようとします。ここで、ContextをSugarに次のように渡します。

_SugarContext.init(getInstrumentation().getContext());
_

テストを実行すると、このエラーが発生します:(この質問を簡潔に読むために切り捨てています)

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

私がすでに試みたトラブルシューティング:

  • テストパッケージが_.test_パッケージ名をSugarORMに渡すための別のマニフェストを保持します。行動に変化なし
  • 他のようにMessageRequestIdModel.findById(MessageRequestIdModel.class, (long) 1);を追加するSO投稿。エラーをそれ自体に変更します(役立つ場合は、ここに完全なスタックトレースを表示します):

    _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)
    _
  • 多くの人が提案したように、マニフェストからすべてのSugar ORM構成を削除しようとしました-これは何も変更しません

  • スタンドアロンアプリがエミュレーター/デバイスで適切なリソースを取得できない場合に備えて、サンプルアプリモジュールを作成し、そのアプリのテストケースとして実行してみました(両方でテストしました)

  • データベースのVERSION番号を増やしてみました

  • ActivityTestCaseに切り替えてgetActivity().getApplicationContext()を使用してみました。これは基本的に失敗し、このコンテキストはSQLiteをセットアップするのに不完全であることを示唆するエラーが表示されます

ご覧のように、私は一晩中このボルダーに力を入れてきましたが、現時点ではSisypheanのようであり、Sugarとは異なるORMを使用する以外に、次のデバッグの試みはまったくありません(実際にはそうではありません)。問題のようです)。テストケースでSQLiteを実行できないことは何よりも優雅で、私はあなたの聖プログラマの意識に助けを求めて叫びます:-'(

18
Angad

これで、Sugar ORMをそのまま使えるようにするのに苦労しているすべての人々がこの問題を最終的に解決するはずです-SQLバージョン管理システムを使用して、手動で作成SQLを起動します。

上記のユースケースでは、次のようになります。

1.)Sugar ORM設定のDBバージョンを新しい番号(Nなど)に変更して、現在のバージョン[〜#〜]または[〜#〜]データベース名を変更

2.)SQLを使用してファイル_ModuleName/src/main/assets/sugar_upgrades/<N>.sql_を作成します。それが役立つ場合に備えて私のものを示す:

DROP TABLE MESSAGE_REQUEST_ID_MODEL;

CREATE TABLE MESSAGE_REQUEST_ID_MODEL(ID INTEGER PRIMARY KEY AUTOINCREMENT、MESSAGE_REQUEST_ID CHAR(128));

これにより、SugarはSQLを起動してテーブルを作成します(手動ではあります)。

補足事項

  • Sugar ORMマニュアルのこのセクションは、この(ハックではありますが)修正のインスピレーションです: http://satyan.github.io/sugar/migration.html
  • Sugar configからパッケージ名をコメントアウトしました
  • SugarはInstrumentation Application Contextで動作します。 InstrumentationTestCaseの基本クラスでは、元の質問に示されているようにSugarContext.init(getInstrumentation().getTargetContext())を実行するだけです
8
Angad

この問題はAndroid Studio 2.x.x-betaバージョン(特に2.0.0-beta6)で確認されており、「インスタントラン」機能に根本的な原因があります。

これはまもなく修正されると思いますが、当面はこれを機能させるには、次のメニューで機能を無効にする必要があります

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

アプリケーションをクリーニングしてからビルドすると、これらの問題が解決するはずです。

関連するSugarバグレポート こちら をご覧ください。

23
Ed George

問題はクラスの作成かもしれません...

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;
    }
}

私のコードで再確認してください。

1
rockstar