数据填充
数据库播种是一种使用运行和使用应用程序所需的一些初始数据来设置应用程序的方法。例如:
- 在部署和运行你的应用程序之前,创建播种器以插入 countries、states 和 cities。
- 或播种机将用户插入数据库中以进行本地开发。
播种机存储在 database/seeders
目录中。你可以通过运行以下 Ace 命令来创建新的种子文件。
node ace make:seeder User
# CREATE: database/seeders/User.ts
每个种子文件都必须扩展 BaseSeeder
类并实现 run
方法。
以下示例使用 Lucid 模型创建多个用户。但是,也可以直接使用数据库查询生成器。 换句话说,播种机不关心你在 run
方法中写了什么。
// 文件名: database/seeders/User.ts
import BaseSeeder from '@ioc:Adonis/Lucid/Seeder'
import User from 'App/Models/User'
export default class UserSeeder extends BaseSeeder {
public async run () {
await User.createMany([
{
email: 'virk@adonisjs.com',
password: 'secret',
},
{
email: 'romain@adonisjs.com',
password: 'supersecret'
}
])
}
}
运行播种机
你可以通过运行以下 Ace 命令来执行所有或选定的数据库播种程序。
# 全部运行
node ace db:seed
你可以多次定义 --files
标志以运行多个文件。此外,你必须定义播种程序文件的完整路径。 我们选择了完整路径,因为你的终端 shell 可以为自动完成路径。
node ace db:seed --files "./database/seeders/User.ts"
你还可以通过在交互模式下运行 db:seed
命令以交互方式选择种子文件。
node ace db:seed -i
仅开发环境运行的播种机
Lucid 允许你仅通过将 developmentOnly
属性设置为 true
来将种子文件标记为仅开发环境适用,这可确保你不会错误地使用虚拟数据为生产数据库播种。
使用 developmentOnly
标志的播种器仅在 NODE_ENV
环境变量设置为 development
时运行。
import BaseSeeder from '@ioc:Adonis/Lucid/Seeder'
export default class UserSeeder extends BaseSeeder {
public static developmentOnly = true
public async run () {
}
}
幂等操作
与迁移不同,数据库播种机没有跟踪系统。换句话说,多次执行播种器会执行多次插入。
根据播种机的性质,你可能想要也可能不想要这种行为。例如:
- 可以多次运行
PostSeeder
并增加数据库中的帖子数量。 - 另一方面,你希望
CountrySeeder
只执行一次插入,这些类型的播种机是幂等的。
幸运的是,Lucid 模型内置了对使用 updateOrCreate
或 fetchOrCreateMany
的幂等操作的支持。考虑到 CountrySeeder
,以下是仅创建一次国家/地区的示例。
import BaseSeeder from '@ioc:Adonis/Lucid/Seeder'
import Country from 'App/Models/Country'
export default class CountrySeeder extends BaseSeeder {
public async run () {
const uniqueKey = 'isoCode'
await Country.updateOrCreateMany(uniqueKey, [
{
isoCode: 'IN',
name: 'India',
},
{
isoCode: 'FR',
name: 'France',
},
{
isoCode: 'TH',
name: ' Thailand',
},
])
}
}
在上面的示例中,updateOrCreateMany
方法将使用 isoCode
代码在数据库中查找现有行,并且只插入缺少的行,因此运行 CountrySeeder
多次不会插入重复的行。
自定义数据库连接
db:seed
命令接受可选的 --connection
标志并将其作为 connection
属性转发到播种器文件。然后,你可以使用此属性在模型交互期间设置适当的连接。例如:
import BaseSeeder from '@ioc:Adonis/Lucid/Seeder'
import User from 'App/Models/User'
export default class UserSeeder extends BaseSeeder {
public async run () {
await User.create({
email: 'virk@adonisjs.com',
password: 'secret',
}, {
connection: this.connection, // 👈
})
}
}
现在你可以在 db:seed
命令上指定 --connection
标志,UserSeeder
将使用它。
node ace db:seed --connection=tenant-1
播种机配置
播种机的配置存储在连接配置对象下的 config/database.ts
文件中。
paths
定义加载数据库种子文件的路径。你还可以定义已安装包的路径。
{
mysql: {
client: 'mysql',
seeders: {
paths: ['./database/seeders', '@somepackage/seeders-dir']
}
}
}
自定义播种机顺序
db:seed
命令按照它们在文件系统中的存储顺序运行所有播种机。
如果你希望某些播种机在其他播种机之前运行,那么您可以为文件名添加计数器前缀或你可以创建一个主播种机目录,如下所示。
步骤 1. 创建主播种机
通过运行以下 Ace 命令创建主播种器文件。
node ace make:seeder MainSeeder/index
# CREATE: database/seeders/MainSeeder/Index.ts
步骤 2. 在 seeders
配置中注册其路径
打开 config/database.ts
文件并将路径注册到连接配置中的 Main seeder 目录。
进行以下更改后,db:seed
命令将扫描 ./database/seeders/MainSeeder
目录。
{
mysql: {
client: 'mysql',
// ... 其余配置
seeders: {
paths: ['./database/seeders/MainSeeder']
}
}
}
步骤 3. 在主播种机中导入其他播种机
现在,你可以手动导入 Main seeder 文件中的所有播种机,并以你想要的任何顺序执行。
注意:以下是 Main 播种器的示例实现,随意根据你的要求对其进行自定义修改。
import BaseSeeder from '@ioc:Adonis/Lucid/Seeder'
import Application from '@ioc:Adonis/Core/Application'
export default class IndexSeeder extends BaseSeeder {
private async runSeeder(seeder: { default: typeof BaseSeeder }) {
/**
* 不要在非开发模式和播种机仅开发环境时运行
*/
if (seeder.default.developmentOnly && !Application.inDev) {
return
}
await new seeder.default(this.client).run()
}
public async run() {
await this.runSeeder(await import('../Category'))
await this.runSeeder(await import('../User'))
await this.runSeeder(await import('../Post'))
}
}
步骤 4. 运行 db:seed
命令
node ace db:seed
# 完成 database/seeders/MainSeeder/Index
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。