首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >app新安装时Appcelerator合金迁移引发SQL错误

app新安装时Appcelerator合金迁移引发SQL错误
EN

Stack Overflow用户
提问于 2017-01-23 17:14:26
回答 2查看 270关注 0票数 1

在我的应用程序中,我有一个带有一些列的模型,需要添加一个新列。

因此,根据文档,我编写了一个带有SQL "alter列..“的迁移文件。并将该属性添加到合金模型文件中。就像预期的那样,这一切都很完美。

但是,当应用程序第一次安装在设备上时,会抛出一个SQL错误,说明我的迁移尝试添加的列已经存在。由于数据库模式是从模型文件中创建的,所以我认为异常是正确的,但我想知道如何为现有和新安装的应用程序完成数据库更改。移除迁移文件,只需将属性添加到模型文件中,就可以使其在新安装时工作,而不是在更新时工作。

向你问好,斯文

更新1:我尝试添加一个初始迁移,创建没有新字段的表,然后在另一个迁移中添加新字段(请参阅来自的答案)。还是同样的错误。

应用程序版本: 5.2.2

模型-适配器类型: sqlrest

更新2(一些代码):

模型:

代码语言:javascript
复制
config: {
URL: Alloy.Globals.jsonEndPoint + Alloy.Globals.jsonRequestParams + "foto",
columns:{
    id:                                     "INTEGER PRIMARY KEY AUTOINCREMENT",
    dateiname:                              "TEXT",
    beschreibung:                           "TEXT",
    primaerfoto:                            "TEXT",
    aufnahmedatum:                          "TEXT",
    anlage_id:                              "INTEGER",
    foto_label_id:                          "INTEGER",
    latest_sync_date:                       "TEXT",
    dirty:                                  "INTEGER",
    begehungsbericht_protokoll_id:          "INTEGER",          
    begehungsbericht_protokoll_server_id:   "INTEGER",          
},
adapter: {
    remoteBackup: false,                        //Prevent database from being saved in icloud   
    db_name: this.Alloy.Globals.currentDatabase,
    type: "sqlrest",
    collection_name: "foto",
    idAttribute: "id"
}

移徙1:

代码语言:javascript
复制
migration.up = function(migrator) {
Ti.API.info(">>>>>>>>>>>>>>>> migrate create table UP <<<<<<<<<<<<<");
migrator.createTable({
    columns: {
        id:                                     "INTEGER PRIMARY KEY AUTOINCREMENT",
        dateiname:                              "TEXT",
        beschreibung:                           "TEXT",
        primaerfoto:                            "TEXT",
        aufnahmedatum:                          "TEXT",
        anlage_id:                              "INTEGER",
        foto_label_id:                          "INTEGER",
        latest_sync_date:                       "TEXT",
        dirty:                                  "INTEGER",
        begehungsbericht_protokoll_id:          "INTEGER",
    }
});

移徙2:

代码语言:javascript
复制
migration.up = function(migrator) {
Ti.API.info(">>>>>>>>>>>>>>>> migrate ALTER table UP <<<<<<<<<<<<<");
migrator.db.execute('ALTER TABLE foto ADD COLUMN begehungsbericht_protokoll_server_id INTEGER;');

};

更新3(解决方案和解决方案):,因为我知道表在运行迁移时应该拥有的列数,所以我使用这些信息添加列的条件(就像Cesar建议的那样)。

代码语言:javascript
复制
migration.up = function(migrator) {
Ti.API.info("migrating foto table");

var rows = migrator.db.execute("SELECT * FROM foto");
Ti.API.info("field count: " + rows.fieldCount);

if (rows.fieldCount < 11) {
    Ti.API.info("adding column: begehungsbericht_protokoll_server_id");
    migrator.db.execute('ALTER TABLE foto ADD COLUMN begehungsbericht_protokoll_server_id INTEGER');
} else {
    Ti.API.info("NOT adding column: begehungsbericht_protokoll_server_id");
} 

};

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-01-23 18:41:29

DB迁移始终是应用程序开发中的一个复杂部分。尽管如此,还是有一些优点和缺点,它们会使您在某一时刻彻底消除整个DB,并在重大更新时从头开始。

的好处是应该能够通过在migration.up函数中执行一个简单的SELECT和验证它是否是使用http://docs.appcelerator.com/platform/latest/#!/api/Titanium.Database.ResultSet-method-isValidRow成功的查询来检查列是否存在。

您还可以通过添加一个Alloy.Globals属性来“版本”您的DB,并对DB模式进行每次更改。类似于Alloy.Globals.DatabaseVersion = 1,并在您的migration.upmigration.down函数中验证这一点,这样您至少知道您在当前DB模式中的位置以及您希望在迁移的DB模式中的位置。

不太好的是,随着每次更改,您将不得不编写代码来管理所有可能的用例(例如,具有版本1的用户跳转到版本3而不转到2),所以在您使用时也要考虑这一点。

票数 0
EN

Stack Overflow用户

发布于 2017-01-24 07:10:06

斯文,首先来看看这个:https://medium.com/all-titanium/using-models-and-migrations-in-titanium-a03e3a6b0d6f#.2qb9oj3rh

我认为您所面临的问题是,您需要使用createTable进行初始迁移,使您的初始模型设置具有此功能。然后应用迁移。那应该管用。

射线

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41811912

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档