TypeScript中使用Dexie的Version.upgrade()升级并填充数据表
用Dexie.js的Version.upgrade()在TypeScript中升级并填充数据表
嘿,我来帮你搞定这个Dexie版本升级和数据填充的事儿!你已经基于官方TS示例扩展了代码,接下来咱们把Version.upgrade()的逻辑加进去,一步步来:
第一步:补全接口与数据库类定义
首先先把你提到的ICity和其他接口补全,然后在AppDatabase里定义版本规则和升级逻辑:
export interface ICity { id?: number; name: string; } // 补全你示例中提到的其他接口,避免代码报错 export interface IContact { id?: number; name: string; } export interface IEmailAddress { id?: number; contactId: number; email: string; } export interface IPhoneNumber { id?: number; contactId: number; number: string; } export class AppDatabase extends Dexie { contacts: Dexie.Table<IContact, number>; emails: Dexie.Table<IEmailAddress, number>; phones: Dexie.Table<IPhoneNumber, number>; cities: Dexie.Table<ICity, number>; // 新增的城市表 constructor() { super('AppDatabase'); // 版本1:初始表结构(对应你原来的contacts、emails、phones表) this.version(1).stores({ contacts: '++id, name', emails: '++id, contactId, email', phones: '++id, contactId, number' }); // 版本2:新增cities表,同时在升级时填充初始数据 this.version(2).stores({ cities: '++id, name' // 只需要定义新增/变更的表结构 }).upgrade(async (tx) => { // 这里就是升级时的逻辑,咱们批量插入一些城市数据 const initialCities: ICity[] = [ { name: '北京' }, { name: '上海' }, { name: '广州' }, { name: '深圳' } ]; // 注意要用tx.table()操作表,因为升级是在事务上下文里执行的 await tx.table('cities').bulkAdd(initialCities); console.log('城市表创建并填充完成!'); }); // 把表绑定到类的属性上,方便后续调用 this.contacts = this.table('contacts'); this.emails = this.table('emails'); this.phones = this.table('phones'); this.cities = this.table('cities'); } }
第二步:搞懂升级逻辑的核心点
- 版本号必须递增:每次修改数据库结构或者需要填充数据,都得把版本号往上加,不能回退版本号,Dexie靠版本号判断是否需要执行升级逻辑。
- stores()只写变更:不用重复写旧版本已经定义过的表,Dexie会自动保留之前的表结构,只处理你在新版本里声明的表变更。
- upgrade()是异步的:一定要用
async/await或者返回Promise,不然Dexie可能会在数据没填充完就结束升级,导致数据丢失。
第三步:测试升级后的数据库
接下来就可以正常使用这个数据库了,比如测试下城市数据有没有被成功填充:
const db = new AppDatabase(); // 读取所有城市数据 db.cities.toArray().then(cities => { console.log('数据库里的城市:', cities); }).catch(err => { console.error('读取城市数据出错:', err); });
额外小提示
- 如果是要修改现有表的结构(比如给contacts表加个
age字段),也要在对应版本的stores()里更新,然后在upgrade()里给旧数据补值,比如:this.version(3).stores({ contacts: '++id, name, age' // 新增age索引 }).upgrade(async (tx) => { // 给旧的contact数据默认设置age为30 const contacts = await tx.table('contacts').toArray(); await Promise.all(contacts.map(contact => tx.table('contacts').update(contact.id!, { age: 30 }) )); }); - 如果是第一次创建数据库就要填充初始数据,别用
upgrade(),用populate事件更合适,比如:this.on('populate', async () => { // 只有数据库第一次创建时才会触发这个事件 await db.contacts.bulkAdd([ { name: '张三' }, { name: '李四' } ]); });
内容的提问来源于stack exchange,提问作者kabeleced
相关产品推荐
相关产品推荐

