Javascript PersistenceJS:使用migrate()更新现有数据库
我目前正在尝试使用PersistenceJS的迁移插件对现有数据库进行更改。我可以在数据库中添加/编辑/删除项目,但是Javascript PersistenceJS:使用migrate()更新现有数据库,javascript,html,persistence,Javascript,Html,Persistence,我目前正在尝试使用PersistenceJS的迁移插件对现有数据库进行更改。我可以在数据库中添加/编辑/删除项目,但是 如何向现有(!)表中添加列 如何更改现有(!)列的类型,例如从“文本”更改为“整数” 这些更改应保留当前的现有数据。 遗憾的是,文档有点少,也许你能帮忙 以下是当前的工作设置: 有点作用的迁移代码: 结果… 调用migrate()只会登录到“migration init”,不会调用完整的处理程序,也不会创建“due”列 在调用migrate()之前不调用schemaAsyn
- 如何向现有(!)表中添加列
- 如何更改现有(!)列的类型,例如从“文本”更改为“整数”
这些更改应保留当前的现有数据。
persistence.store.websql.config(persistence,'newdatabase','testingmigration',5*1024*1024)代码>,不调用schemaAsync()并且只调用migrate()将成功地记录“migration complete!”——但是它在一个新的、完全空的数据库“newdatabase”中这样做,这当然不会保留任何现有数据
persistence.store.websql.config(…)
,persistence.define('Todo',…)
和persistence.schemaAsync()
创建的
我现在想保留数据库中已经存在的所有数据,但我想
- 将列
优先级
的类型从“整数”更改为“文本”
- 将类型为“日期”的列
添加到所有现有TODOdue
谢谢 我终于让它工作了。我的初始需求中有许多问题,我想指出以供将来参考。请看第一个迁移定义:
persistence.defineMigration(1, {
up: function() {
this.createTable('Todo', function(t){
...
毫不奇怪,
createTable
将执行以下操作:它将执行SQL语句'createtablettodo…
,如果已经有一个名为Todo
的表,该语句将自动失败并停止迁移。这就是为什么它使用新数据库,而不是现有数据库。请记住:我已经有了一个实时数据库,其中的表“Todo”需要更新。如果您是从新开始的(即,您没有使用过schemaAsync
),那么createTable
工作正常。由于迁移插件不提供createTableIfNotExists
方法,因此我需要使用executeSql
,如下所示:
persistence.defineMigration(1, {
up: function() {
this.executeSql('CREATE TABLE IF NOT EXISTS Todo (id VARCHAR(32) PRIMARY KEY, task TEXT, priority INT, done BOOL)');
...
现在,从架构版本0到1的迁移成功了,到版本2的迁移也成功了 随着迁移到版本3,
priority
列的类型需要从int
更改为text
。这通常使用ALTER COLUMN
SQL命令来完成,而Web SQL/SQLite不支持该命令。请参见
使用SQLite更改列需要4步解决方法:
persistence.defineMigration(3, {
up: function() {
// rename current table
this.executeSql('ALTER TABLE Todo RENAME TO OldTodo');
// create new table with required columns and column types
this.executeSql('CREATE TABLE Todo (id VARCHAR(32) PRIMARY KEY, task TEXT, priority TEXT, done BOOL)');
// copy contents from old table to new table
this.executeSql('INSERT INTO Todo(id, task, priority, done) SELECT id, task, priority, done FROM OldTodo');
// delete old table
this.executeSql('DROP TABLE OldTodo');
},
...
当然,更改列类型后,“Todo”的实体定义也应更改:
var Todo = persistence.define('Todo', {
task: 'TEXT',
priority: 'TEXT', // was 'INT'
due: 'DATE',
done: 'BOOL'
});
最后,完整的来源:
这是一个很好的解释,谢谢!但我想我知道一个更容易实现的方法 我和你一样也遇到了同样的麻烦:我得到了一组用
persistence.define
描述的模式,并用persistence.schemaAsync
创建
这就是我的特殊情况:
// This is my mixin for all schemas
var Versioned = persistence.defineMixin('Versioned', {
serverId: "TEXT",
intVersion: "INT",
dtSynced: "DATE",
dtCreatedAt: "DATE",
dtUpdatedAt: "DATE",
delete: "BOOL",
update: "BOOL",
add: "BOOL",
isReadOnly: "BOOL"
});
// This is one of the schemas I need to update with a new field.
var Person = persistence.define('Person', {
fullName: "TEXT",
rate: "INT"
});
//... More schema definitions
// Setup mixin
Person.is(Versioned);
// Sync schemas
persistence.schemaSync();
嗯。没什么特别的。现在,在我的应用程序投入生产几个月后,我想在个人
模式中添加一个新字段isEmployed
根据文档,我应该将所有模式定义重写到迁移中,并停止使用persistence.schemaAsync()
。但我不想重写我所有的定义。相反,我在PersistenceJS init代码后面定义了一个新的迁移:
// Init ORM
persistence.store.websql.config(
persistence,
'Sarafan',
'0.0.2',
'Sarafan.app database',
100 * 1024 * 1024,
0
);
// Define Migrations
persistence.defineMigration(1, {
up: function () {
this.addColumn('Person', 'isEmployed', 'BOOL');
}
});
// ... describing isVersioned mixin
// Updated schema definition with a new field 'isEmployed'
var Person = persistence.define('Person', {
fullName: "TEXT",
rate: "INT",
isEmployed: "BOOL"
});
//... More schema definitions
// Setup mixin
Person.is(Versioned);
// Apply the migration right away from the schemaSync call.
persistence.schemaSync(function (tx) {
persistence.migrations.init(function () {
persistence.migrate(function(){
// Optional callback to be executed after initialization
});
});
});
就这样!我测试这种方法只是为了向模式中添加新字段
让我知道它是否对你有效
persistence.store.websql.config(persistence, 'tododatabase', 'todos are fun', 5*1024*1024);
// persistence.debug = true;
//v0 + v1
// var Todo = persistence.define('Todo', {
// task: 'TEXT',
// priority: 'INT',
// done: 'BOOL'
// });
//v2
// var Todo = persistence.define('Todo', {
// task: 'TEXT',
// priority: 'INT',
// due: 'DATE',
// done: 'BOOL'
// });
//v3
var Todo = persistence.define('Todo', {
task: 'TEXT',
priority: 'TEXT',
due: 'DATE',
done: 'BOOL'
});
persistence.defineMigration(1, {
up: function() {
this.executeSql('CREATE TABLE IF NOT EXISTS Todo (id VARCHAR(32) PRIMARY KEY, task TEXT, priority INT, done BOOL)');
},
down: function() {
this.dropTable('Todo');
}
});
persistence.defineMigration(2, {
up: function() {
this.addColumn('Todo', 'due', 'DATE');
},
down: function() {
this.removeColumn('Todo', 'due');
}
});
persistence.defineMigration(3, {
up: function() {
// rename current table
this.executeSql('ALTER TABLE Todo RENAME TO OldTodo');
// create new table with required columns
this.executeSql('CREATE TABLE Todo (id VARCHAR(32) PRIMARY KEY, task TEXT, priority TEXT, due DATE, done BOOL)');
// copy contents from old table to new table
this.executeSql('INSERT INTO Todo(id, task, priority, due, done) SELECT id, task, priority, due, done FROM OldTodo');
// delete current table
this.executeSql('DROP TABLE OldTodo');
},
down: function() {
this.executeSql('ALTER TABLE Todo RENAME TO OldTodo');
this.executeSql('CREATE TABLE Todo (id VARCHAR(32) PRIMARY KEY, task TEXT, priority INT, due DATE, done BOOL)');
this.executeSql('INSERT INTO Todo(id, task, priority, due, done) SELECT id, task, priority, due, done FROM OldTodo');
this.executeSql('DROP TABLE OldTodo');
}
});
function migrate( callback ){
console.log('migrating...');
persistence.migrations.init( function(){
console.log('migration init');
persistence.migrate( function(){
console.debug('migration complete!');
callback();
} );
});
};
migrate( onMigrationComplete );
function onMigrationComplete(){
// database is ready. do amazing things...
};
// This is my mixin for all schemas
var Versioned = persistence.defineMixin('Versioned', {
serverId: "TEXT",
intVersion: "INT",
dtSynced: "DATE",
dtCreatedAt: "DATE",
dtUpdatedAt: "DATE",
delete: "BOOL",
update: "BOOL",
add: "BOOL",
isReadOnly: "BOOL"
});
// This is one of the schemas I need to update with a new field.
var Person = persistence.define('Person', {
fullName: "TEXT",
rate: "INT"
});
//... More schema definitions
// Setup mixin
Person.is(Versioned);
// Sync schemas
persistence.schemaSync();
// Init ORM
persistence.store.websql.config(
persistence,
'Sarafan',
'0.0.2',
'Sarafan.app database',
100 * 1024 * 1024,
0
);
// Define Migrations
persistence.defineMigration(1, {
up: function () {
this.addColumn('Person', 'isEmployed', 'BOOL');
}
});
// ... describing isVersioned mixin
// Updated schema definition with a new field 'isEmployed'
var Person = persistence.define('Person', {
fullName: "TEXT",
rate: "INT",
isEmployed: "BOOL"
});
//... More schema definitions
// Setup mixin
Person.is(Versioned);
// Apply the migration right away from the schemaSync call.
persistence.schemaSync(function (tx) {
persistence.migrations.init(function () {
persistence.migrate(function(){
// Optional callback to be executed after initialization
});
});
});