in my application I am having a model with some columns, which needs to be added a new column.
So according to the documentation I wrote an migration file with an SQL "alter table add column.." and added the property to the alloy model file as well. Like expected this worked perfectly.
But when the app is installed on a device for the first time an SQL error is thrown saying that the column my migration is trying to add is already existing. Since the database schema is created from the model files I guess the exception is correct, but I am wondering howto accomplish a database change for existing and freshly installed APPS. Removing the migration file, just adding the property to the model file will make it work on fresh installation, but not on updates.
Best regards, Sven
Update 1: I tried adding an initial migration creating the table without the new field and then adding the new field in another migration (see answer from Ray). Still the same error.
Appcelerator Version: 5.2.2
Model-adapter-type: sqlrest
Update 2 (some Code):
model:
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"
}
migration 1:
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",
}
});
migration 2:
migration.up = function(migrator) {
Ti.API.info(">>>>>>>>>>>>>>>> migrate ALTER table UP <<<<<<<<<<<<<");
migrator.db.execute('ALTER TABLE foto ADD COLUMN begehungsbericht_protokoll_server_id INTEGER;');
};
Update 3 (solution with workaround): Since I know the number of columns the table should have when running the migration I use this information for a conditional adding of the column (like Cesar proposed).
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");
}
};