createConnection
我遇到了同样的问题,并通过提供以下属性作为选项,设法让迁移在反应本机上下文中运行:
- 同步:
false
- 迁移运行:
true
- 迁移:[
migrationFile
]
其中migrationFile
直接导入(而不是使用文件路径正则表达式),如下所示(使用内联 SQL 语句):
import { MigrationInterface } from 'typeorm'
module.exports = class PostRefactoring1579804977343 implements MigrationInterface {
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "workouts" ADD COLUMN "questionSetId" text`)
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "workouts" DROP COLUMN "questionSetId"`)
}
}
上面的迁移文件看起来与您将在https://typeorm.io/#/migrations上看到的示例略有不同,因为我没有使用 TypeScript,module.exports
而且我在直接导入文件时必须添加
似乎让它在 react-native 中工作的主要(几乎)未记录的发现是migrationsRun
我在这里发现的神奇属性reactnativeconnectionoptions
随着时间的推移,您可以migrations
根据需要将更多迁移文件添加到阵列配置中,并确保为它们提供具有适当时间戳的唯一类名。它似乎保留了已运行迁移的设备日志 - 以阻止它们在同一设备上多次运行
注意:要求synchronize: false
意味着您需要在首次安装应用程序时对架构进行初始同步(我最初使用 AsyncStorage 中的标志设置以指示首次应用程序安装)
替代方法
上述方法意味着我们在初始用户安装后手动维护我们的架构设置。而我非常喜欢在可能的情况下自动管理架构的想法 - 迁移仅用于操作数据。
因此,实现此目的的另一种方法是在初始化连接时直接调用synchronize
and方法。runMigrations
在这种情况下,您需要检查迁移脚本中是否存在特定的表,因为它们将首先运行,因此如果用户在安装后第一次打开应用程序,它们需要更新的表可能还不存在
连接选项:
export const initialiseDataStoreService = async () => {
const connection = await createConnection({
type: 'react-native',
database: 'main.sqlite',
location: 'default',
logging: [ 'error', 'schema'],
entities: [
CoreData,
Workouts,
],
migrations: [PostRefactoring1579804977343],
})
await connection.runMigrations()
await connection.synchronize()
return connection
}
更新的迁移脚本:
import { MigrationInterface, TableColumn } from 'typeorm'
module.exports = class PostRefactoring1579804977343 implements MigrationInterface {
async up(queryRunner) {
const hasWorkoutsTable = await queryRunner.hasTable('workouts')
if (hasWorkoutsTable) {
await queryRunner.addColumn(
'workouts',
new TableColumn({
name: 'questionSetId',
type: 'text',
// we make the new field nullable in order to enable the update
// for existing data (schema sync will later update this column to be non
// nullable)
isNullable: true,
}),
)
await queryRunner.query(
`UPDATE workouts SET questionSetId = "MIGRATION-PLACEHOLDER" WHERE questionSetId IS NULL`,
)
}
}
async down(queryRunner) {
const hasWorkoutsTable = await queryRunner.hasTable('workouts')
if (hasWorkoutsTable) {
await queryRunner.dropColumn('workouts', 'questionSetId')
}
}
}