【问题标题】:Sugar ORM just won't create tablesSugar ORM 不会创建表
【发布时间】:2016-03-03 07:28:36
【问题描述】:

我正在开发一个需要持久化简单模型的独立库项目。这是我的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...

我已经尝试过的故障排除:

  • 为测试包保留不同的 Manifest 以将 .test 包名称传递给 SugarORM。行为没有改变
  • 像在其他 SO 帖子中一样添加 MessageRequestIdModel.findById(MessageRequestIdModel.class, (long) 1);。将错误更改为自身(在此处显示完整的堆栈跟踪以防万一):

    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

如您所见,我整晚都在努力推动这块巨石,但此时它似乎是西西弗斯,除了使用与 Sugar 不同的 ORM(它不会'似乎不是问题)。没有什么比不能在测试用例中运行 SQLite 更令人沮丧的了,我向你神圣的程序员意识求助:-'(

【问题讨论】:

  • 您使用的是哪个版本的 Android Studio?可能与following issue有关
  • @EdGeorge 看起来非常不错!
  • 那我把它添加为答案:)
  • @EdGeorge 然而,我在 Gradle 1.5.0 上 :( 虽然是的,但它肯定可能对某人有所帮助 - 会关注这个问题,如果这解决了它,它将切换为接受的答案!

标签: android sqlite android-sqlite android-testing sugarorm


【解决方案1】:

此问题已在 Android Studio 2.x.x-beta 版本(尤其是 2.0.0-beta6)中观察到,其根本原因在于“即时运行”功能。

我想这可能会很快得到解决,但为了在此期间正常工作,您应该在以下菜单中禁用该功能

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

清理然后构建应用程序应该可以解决这些问题。

您可以查看相关的 Sugar 错误报告here

【讨论】:

  • 这个问题现在已经修复并在 master 分支中。请参阅 github.com/satyan/sugar/pull/564 它尚未正式发布,但 compile 'com.github.satyan:sugar:b16e65326a' 已修复(使用 jitpack)
  • 获得 AS 2.3.1 并使用最新的糖 .. 仍然是同样的错误 :(
  • 我禁用了即时运行,我得到了同样的错误:(
【解决方案2】:

对于所有努力让 Sugar ORM 开箱即用的人来说,这应该最终解决了这个问题 - 使用 SQL 版本控制系统手动触发创建 SQL。

在上述用例中,您可以这样做:

1.) 将 Sugar ORM 配置的数据库版本更改为一个新数字(例如 N),使其大于当前版本更改数据库名称

2.) 使用您的 SQL 创建文件 ModuleName/src/main/assets/sugar_upgrades/&lt;N&gt;.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 手册的这一部分是这个(虽然是 hacky)修复背后的灵感:http://satyan.github.io/sugar/migration.html
  • 我已经从 Sugar config 中注释掉了包名
  • Sugar 与仪器应用程序上下文一起工作。在InstrumentationTestCase 的基类中,只需执行SugarContext.init(getInstrumentation().getTargetContext()) 即可,如原始问题所示

【讨论】:

  • 你帮了我,这是解决我问题的方法,谢谢 :)
【解决方案3】:

您的问题可能是创建类...

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

请重新检查我的代码。

【讨论】:

  • 您的语法适用于 Sugar ORM 1.3,而我使用的是 Sugar ORM 1.4。在 1.4 中,SugarRecord 没有通用类型参数,这意味着它甚至不会为我编译。
  • 好的。谢谢你的建议。您可以通过 manifest 增加 Suger ORM 的版本并再次运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-05
  • 1970-01-01
  • 2017-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多