lakutata 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -30
- package/README.zh-CN.md +130 -0
- package/dist/cjs/exports/QueueComponent.d.ts +1 -0
- package/dist/cjs/exports/QueueComponent.js +20 -0
- package/dist/esm/exports/QueueComponent.js +1 -0
- package/dist/types/exports/QueueComponent.d.ts +1 -0
- package/doc/en/Application.md +107 -0
- package/doc/en/CLI.md +274 -0
- package/doc/en/Cache.md +379 -0
- package/doc/en/Command.md +110 -0
- package/doc/en/ContainerdIntegration.md +17 -16
- package/doc/en/Controllers.md +256 -0
- package/doc/en/DBus.md +291 -0
- package/doc/en/DTOValidation.md +72 -43
- package/doc/en/Database.md +188 -0
- package/doc/en/DatabaseDrivers.md +287 -0
- package/doc/en/Decorator.md +52 -40
- package/doc/en/DockerIntegration.md +7 -6
- package/doc/en/Entities.md +240 -0
- package/doc/en/Entrypoint.md +216 -0
- package/doc/en/Exceptions.md +174 -0
- package/doc/en/GRPC.md +251 -0
- package/doc/en/GettingStarted.md +165 -0
- package/doc/en/HTTP.md +507 -0
- package/doc/en/HelperFunctions.md +11 -11
- package/doc/en/I18n.md +119 -115
- package/doc/en/Injection.md +144 -0
- package/doc/en/Installers.md +280 -0
- package/doc/en/Logger.md +206 -0
- package/doc/en/MCP.md +293 -0
- package/doc/en/Middlewares.md +213 -0
- package/doc/en/Migrations.md +202 -0
- package/doc/en/MongoEmbedded.md +149 -0
- package/doc/en/Monitor.md +164 -0
- package/doc/en/Mutex.md +27 -25
- package/doc/en/NATS.md +246 -0
- package/doc/en/NativeAddons.md +212 -0
- package/doc/en/Objects.md +143 -0
- package/doc/en/Overview.md +62 -85
- package/doc/en/Packaging.md +193 -0
- package/doc/en/ProjectStructure.md +124 -0
- package/doc/en/Queue.md +269 -0
- package/doc/en/Schedules.md +217 -0
- package/doc/en/Security.md +10 -9
- package/doc/en/ServiceCalls.md +504 -0
- package/doc/en/Time.md +19 -20
- package/doc/en/UpgradingFrom1.md +435 -0
- package/doc/en/UpgradingFrom2.md +315 -0
- package/doc/en/Workspaces.md +189 -0
- package/doc/en/examples/BackgroundJobs.md +677 -0
- package/doc/en/examples/CommandLineTool.md +664 -0
- package/doc/en/examples/DesktopApp.md +809 -0
- package/doc/en/examples/DeviceService.md +607 -0
- package/doc/en/examples/MCPServer.md +653 -0
- package/doc/en/examples/README.md +16 -0
- package/doc/en/examples/RestAPI.md +490 -0
- package/doc/en/examples/ServiceCalls.md +829 -0
- package/doc/en/examples/WebApp.md +568 -0
- package/doc/zh/Application.md +75 -0
- package/doc/zh/CLI.md +250 -0
- package/doc/zh/Cache.md +328 -0
- package/doc/zh/Command.md +78 -0
- package/doc/zh/ContainerdIntegration.md +9 -9
- package/doc/zh/Controllers.md +228 -0
- package/doc/zh/DBus.md +257 -0
- package/doc/zh/DTOValidation.md +49 -19
- package/doc/zh/Database.md +175 -0
- package/doc/zh/DatabaseDrivers.md +261 -0
- package/doc/zh/Decorator.md +25 -18
- package/doc/zh/DockerIntegration.md +6 -6
- package/doc/zh/Entities.md +224 -0
- package/doc/zh/Entrypoint.md +193 -0
- package/doc/zh/Exceptions.md +158 -0
- package/doc/zh/GRPC.md +226 -0
- package/doc/zh/GettingStarted.md +148 -0
- package/doc/zh/HTTP.md +445 -0
- package/doc/zh/HelperFunctions.md +2 -2
- package/doc/zh/I18n.md +26 -26
- package/doc/zh/Injection.md +129 -0
- package/doc/zh/Installers.md +232 -0
- package/doc/zh/Logger.md +188 -0
- package/doc/zh/MCP.md +265 -0
- package/doc/zh/Middlewares.md +198 -0
- package/doc/zh/Migrations.md +178 -0
- package/doc/zh/MongoEmbedded.md +118 -0
- package/doc/zh/Monitor.md +145 -0
- package/doc/zh/Mutex.md +10 -10
- package/doc/zh/NATS.md +207 -0
- package/doc/zh/NativeAddons.md +180 -0
- package/doc/zh/Objects.md +119 -0
- package/doc/zh/Overview.md +46 -71
- package/doc/zh/Packaging.md +154 -0
- package/doc/zh/ProjectStructure.md +102 -0
- package/doc/zh/Queue.md +214 -0
- package/doc/zh/Schedules.md +193 -0
- package/doc/zh/Security.md +6 -6
- package/doc/zh/ServiceCalls.md +459 -0
- package/doc/zh/Time.md +2 -2
- package/doc/zh/UpgradingFrom1.md +347 -0
- package/doc/zh/UpgradingFrom2.md +230 -0
- package/doc/zh/Workspaces.md +150 -0
- package/doc/zh/examples/BackgroundJobs.md +618 -0
- package/doc/zh/examples/CommandLineTool.md +618 -0
- package/doc/zh/examples/DesktopApp.md +748 -0
- package/doc/zh/examples/DeviceService.md +546 -0
- package/doc/zh/examples/MCPServer.md +604 -0
- package/doc/zh/examples/README.md +14 -0
- package/doc/zh/examples/RestAPI.md +458 -0
- package/doc/zh/examples/ServiceCalls.md +765 -0
- package/doc/zh/examples/WebApp.md +520 -0
- package/package.json +46 -17
- package/doc/en/ActionPattern.md +0 -408
- package/doc/en/Core.md +0 -312
- package/doc/en/ORMIntegration.md +0 -341
- package/doc/zh/ActionPattern.md +0 -334
- package/doc/zh/Core.md +0 -256
- package/doc/zh/ORMIntegration.md +0 -319
package/doc/zh/ORMIntegration.md
DELETED
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
# Lakutata ORM 集成
|
|
2
|
-
|
|
3
|
-
框架的 ORM(`@lakutata/orm` 包)基于 [TypeORM](https://typeorm.io) 0.3。`lakutata` 包通过四个子路径重新导出它:
|
|
4
|
-
|
|
5
|
-
| 子路径 | 内容 |
|
|
6
|
-
|---|---|
|
|
7
|
-
| `lakutata/com/database` | `Database` 组件(整个应用共享一个连接)和 `buildDatabaseOptions` |
|
|
8
|
-
| `lakutata/provider/database` | `Database` 提供者(每次解析都有自己的连接)和 `buildDatabaseOptions` |
|
|
9
|
-
| `lakutata/decorator/orm` | TypeORM 的实体装饰器(`@Entity`、`@Column`、关系等) |
|
|
10
|
-
| `lakutata/orm` | TypeORM 的 API:`Repository`、`EntityManager`、`QueryRunner`、查询操作符、`BaseEntity`、迁移、错误类 |
|
|
11
|
-
|
|
12
|
-
更多细节见 `@lakutata/orm` 的 README;实体、查询选项、查询构建器和迁移的用法见 TypeORM 文档。
|
|
13
|
-
|
|
14
|
-
## 1. 安装
|
|
15
|
-
|
|
16
|
-
TypeORM 是该包的依赖,数据库驱动则不是。请按连接的 `type` 安装对应的驱动:
|
|
17
|
-
|
|
18
|
-
| 数据库 | `type` | 需安装 |
|
|
19
|
-
|---|---|---|
|
|
20
|
-
| PostgreSQL、CockroachDB | `postgres`、`cockroachdb` | `pg` |
|
|
21
|
-
| MySQL、MariaDB | `mysql`、`mariadb` | `mysql2` |
|
|
22
|
-
| SQLite | `sqlite` / `better-sqlite3` | `sqlite3` / `better-sqlite3` |
|
|
23
|
-
| 内存中的 SQLite(WebAssembly) | `sqljs` | `sql.js` |
|
|
24
|
-
| Microsoft SQL Server | `mssql` | `mssql` |
|
|
25
|
-
| Oracle | `oracle` | `oracledb` |
|
|
26
|
-
| MongoDB | `mongodb` | `mongodb`(5 或 6) |
|
|
27
|
-
|
|
28
|
-
```shell
|
|
29
|
-
npm install lakutata pg
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## 2. Database 组件
|
|
33
|
-
|
|
34
|
-
`buildDatabaseOptions` 用 TypeORM 的连接选项(`DataSourceOptions`,原样传给 TypeORM)声明一个 `Database` 组件。组件在创建时连接数据库(列入 `bootstrap` 时在启动阶段连接;连接失败会使启动失败),在应用停止时断开。其他对象按名称注入它。
|
|
35
|
-
|
|
36
|
-
```typescript
|
|
37
|
-
import {Application, Component} from 'lakutata'
|
|
38
|
-
import {Inject} from 'lakutata/decorator/di'
|
|
39
|
-
import {buildDatabaseOptions, Database} from 'lakutata/com/database'
|
|
40
|
-
import {Column, CreateDateColumn, Entity, PrimaryGeneratedColumn} from 'lakutata/decorator/orm'
|
|
41
|
-
|
|
42
|
-
@Entity('users')
|
|
43
|
-
class User {
|
|
44
|
-
@PrimaryGeneratedColumn()
|
|
45
|
-
public id: number
|
|
46
|
-
|
|
47
|
-
@Column({type: 'varchar', length: 100})
|
|
48
|
-
public name: string
|
|
49
|
-
|
|
50
|
-
@Column({unique: true})
|
|
51
|
-
public email: string
|
|
52
|
-
|
|
53
|
-
@CreateDateColumn({type: 'timestamptz'})
|
|
54
|
-
public createdAt: Date
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
class Users extends Component {
|
|
58
|
-
//以 "db" 注册的组件
|
|
59
|
-
@Inject('db')
|
|
60
|
-
protected readonly db: Database
|
|
61
|
-
|
|
62
|
-
public async register(name: string, email: string): Promise<User> {
|
|
63
|
-
return await this.db.getRepository(User).save({name: name, email: email})
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
public async find(id: number): Promise<User | null> {
|
|
67
|
-
return await this.db.getRepository(User).findOneBy({id: id})
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
public async rename(id: number, name: string): Promise<void> {
|
|
71
|
-
await this.db.getRepository(User).update({id: id}, {name: name})
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
public async remove(id: number): Promise<boolean> {
|
|
75
|
-
const result = await this.db.getRepository(User).delete({id: id})
|
|
76
|
-
return !!result.affected
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
Application
|
|
81
|
-
.run(() => ({
|
|
82
|
-
id: 'com.example.users',
|
|
83
|
-
name: 'Users',
|
|
84
|
-
components: {
|
|
85
|
-
db: buildDatabaseOptions({
|
|
86
|
-
type: 'postgres',
|
|
87
|
-
host: process.env.DB_HOST ?? 'localhost',
|
|
88
|
-
port: 5432,
|
|
89
|
-
username: 'postgres',
|
|
90
|
-
password: process.env.DB_PASSWORD,
|
|
91
|
-
database: 'users',
|
|
92
|
-
entities: [User],
|
|
93
|
-
//仅用于开发:表结构跟随实体变化;生产环境用迁移修改表结构
|
|
94
|
-
synchronize: true
|
|
95
|
-
}),
|
|
96
|
-
users: {class: Users}
|
|
97
|
-
},
|
|
98
|
-
bootstrap: ['db']
|
|
99
|
-
}))
|
|
100
|
-
.onLaunched(async (app: Application): Promise<void> => {
|
|
101
|
-
const users: Users = await app.getObject<Users>('users')
|
|
102
|
-
await users.register('Ada', 'ada@example.com')
|
|
103
|
-
})
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
常用的连接选项:
|
|
107
|
-
|
|
108
|
-
| 选项 | 含义 |
|
|
109
|
-
|---|---|
|
|
110
|
-
| `type` | 驱动:`'postgres'`、`'mysql'`、`'sqlite'` 等 |
|
|
111
|
-
| `url` 或 `host`、`port`、`username`、`password`、`database` | 服务器和数据库 |
|
|
112
|
-
| `entities` | 实体类、`EntitySchema`,或其编译后文件的 glob 路径(`'dist/entities/*.js'`) |
|
|
113
|
-
| `synchronize` | 每次连接时根据实体更新表结构(默认 `false`):仅用于开发 |
|
|
114
|
-
| `migrations`、`migrationsRun`、`migrationsTransactionMode` | 迁移列表、是否在每次连接时执行(默认 `false`)、迁移的事务方式(默认 `'all'`) |
|
|
115
|
-
| `logging`、`logger` | TypeORM 记录哪些日志以及记录到哪里 |
|
|
116
|
-
| `poolSize`、`extra` | 连接池大小;传给驱动的选项 |
|
|
117
|
-
| `subscribers`、`namingStrategy`、`cache` | 实体订阅者、表名和列名的命名策略、查询结果缓存 |
|
|
118
|
-
|
|
119
|
-
组件提供数据源的 TypeORM API:`getRepository()`、`getTreeRepository()`、`getMongoRepository()`、`manager`、`transaction()`、`query()`、`createQueryBuilder()`、`createQueryRunner()`、`synchronize()`、`runMigrations()`、`undoLastMigration()`、`showMigrations()`。
|
|
120
|
-
|
|
121
|
-
## 3. 实体
|
|
122
|
-
|
|
123
|
-
`lakutata/decorator/orm` 中的装饰器就是 TypeORM 的装饰器(完整列表见 [Decorator](Decorator.md)):
|
|
124
|
-
|
|
125
|
-
```typescript
|
|
126
|
-
import {
|
|
127
|
-
BeforeInsert, Column, CreateDateColumn, DeleteDateColumn, Entity, Index, JoinColumn, ManyToOne, OneToMany,
|
|
128
|
-
PrimaryGeneratedColumn, UpdateDateColumn, VersionColumn
|
|
129
|
-
} from 'lakutata/decorator/orm'
|
|
130
|
-
|
|
131
|
-
@Entity('orders')
|
|
132
|
-
export class Order {
|
|
133
|
-
@PrimaryGeneratedColumn('uuid')
|
|
134
|
-
public id: string
|
|
135
|
-
|
|
136
|
-
@Index()
|
|
137
|
-
@Column()
|
|
138
|
-
public customer: string
|
|
139
|
-
|
|
140
|
-
//随订单一起保存
|
|
141
|
-
@OneToMany(() => OrderLine, (line: OrderLine) => line.order, {cascade: true})
|
|
142
|
-
public lines: OrderLine[]
|
|
143
|
-
|
|
144
|
-
@CreateDateColumn({type: 'timestamptz'})
|
|
145
|
-
public createdAt: Date
|
|
146
|
-
|
|
147
|
-
@UpdateDateColumn({type: 'timestamptz'})
|
|
148
|
-
public updatedAt: Date
|
|
149
|
-
|
|
150
|
-
//由 softDelete() 设置:除非指定 withDeleted,查询会跳过该订单
|
|
151
|
-
@DeleteDateColumn({type: 'timestamptz'})
|
|
152
|
-
public deletedAt: Date | null
|
|
153
|
-
|
|
154
|
-
//每次保存时递增
|
|
155
|
-
@VersionColumn()
|
|
156
|
-
public version: number
|
|
157
|
-
|
|
158
|
-
@BeforeInsert()
|
|
159
|
-
protected normalize(): void {
|
|
160
|
-
this.customer = this.customer.trim()
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
@Entity('order_lines')
|
|
165
|
-
export class OrderLine {
|
|
166
|
-
@PrimaryGeneratedColumn()
|
|
167
|
-
public id: number
|
|
168
|
-
|
|
169
|
-
@Column()
|
|
170
|
-
public product: string
|
|
171
|
-
|
|
172
|
-
@Column('integer')
|
|
173
|
-
public quantity: number
|
|
174
|
-
|
|
175
|
-
@ManyToOne(() => Order, (order: Order) => order.lines, {onDelete: 'CASCADE'})
|
|
176
|
-
@JoinColumn({name: 'order_id'})
|
|
177
|
-
public order: Order
|
|
178
|
-
}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
实体也可以继承 `BaseEntity`(来自 `lakutata/orm`)以使用活动记录风格的操作(`User.findOneBy()`、`user.save()`):它们使用最后一个注册了该实体的连接。
|
|
182
|
-
|
|
183
|
-
## 4. 查询
|
|
184
|
-
|
|
185
|
-
`lakutata/orm` 导出了查询操作符(`In`、`ILike`、`Between`、`MoreThan`、`IsNull`、`Not`、`Raw` 等)、仓储和查询构建器。
|
|
186
|
-
|
|
187
|
-
```typescript
|
|
188
|
-
import {Component} from 'lakutata'
|
|
189
|
-
import {Inject} from 'lakutata/decorator/di'
|
|
190
|
-
import {Database} from 'lakutata/com/database'
|
|
191
|
-
import {Between, ILike, type Repository} from 'lakutata/orm'
|
|
192
|
-
|
|
193
|
-
class Orders extends Component {
|
|
194
|
-
@Inject('db')
|
|
195
|
-
protected readonly db: Database
|
|
196
|
-
|
|
197
|
-
protected get orders(): Repository<Order> {
|
|
198
|
-
return this.db.getRepository(Order)
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
//某段时间内订单的一页,以及订单总数
|
|
202
|
-
public async search(customer: string, from: Date, to: Date, page: number): Promise<[Order[], number]> {
|
|
203
|
-
return await this.orders.findAndCount({
|
|
204
|
-
where: {customer: ILike(`%${customer}%`), createdAt: Between(from, to)},
|
|
205
|
-
order: {createdAt: 'DESC'},
|
|
206
|
-
skip: (page - 1) * 20,
|
|
207
|
-
take: 20
|
|
208
|
-
})
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
//查询构建器
|
|
212
|
-
public async findByCustomer(customer: string): Promise<Order[]> {
|
|
213
|
-
return await this.db.createQueryBuilder(Order, 'order')
|
|
214
|
-
.where('order.customer LIKE :customer', {customer: `%${customer}%`})
|
|
215
|
-
.orderBy('order.createdAt', 'DESC')
|
|
216
|
-
.getMany()
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
//原生 SQL:PostgreSQL 的占位符是 $1、$2…
|
|
220
|
-
public async count(customer: string): Promise<number> {
|
|
221
|
-
const rows: { count: string }[] = await this.db.query('SELECT COUNT(*) AS count FROM orders WHERE customer = $1', [customer])
|
|
222
|
-
return Number(rows[0].count)
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
## 5. 事务
|
|
228
|
-
|
|
229
|
-
`transaction([isolationLevel], fn)` 在事务中执行函数:函数完成时提交,失败时回滚(并重新抛出其错误)。事务中的操作要通过传给函数的实体管理器执行;通过 `db.manager` 或 `db.getRepository()` 执行的操作不在该事务中。`createQueryRunner()` 用于手动控制事务。
|
|
230
|
-
|
|
231
|
-
```typescript
|
|
232
|
-
import {Component} from 'lakutata'
|
|
233
|
-
import {Inject} from 'lakutata/decorator/di'
|
|
234
|
-
import {Database} from 'lakutata/com/database'
|
|
235
|
-
import {type EntityManager} from 'lakutata/orm'
|
|
236
|
-
|
|
237
|
-
class Signup extends Component {
|
|
238
|
-
@Inject('db')
|
|
239
|
-
protected readonly db: Database
|
|
240
|
-
|
|
241
|
-
//两次保存要么都成功,要么都不生效
|
|
242
|
-
public async signup(name: string, email: string, product: string): Promise<User> {
|
|
243
|
-
return await this.db.transaction('SERIALIZABLE', async (manager: EntityManager): Promise<User> => {
|
|
244
|
-
const user: User = await manager.save(User, {name: name, email: email})
|
|
245
|
-
await manager.save(Order, {customer: email, lines: [{product: product, quantity: 1}]})
|
|
246
|
-
return user
|
|
247
|
-
})
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
## 6. Database 提供者
|
|
253
|
-
|
|
254
|
-
`lakutata/provider/database` 中的提供者与组件的 API 相同,但它是瞬态的:每次解析(`@Inject`、`getObject()`)都会创建一个新实例,该实例打开自己的连接池,并在随创建它的对象或容器一起销毁时关闭。它适合短时使用(任务、脚本、租户数据库);应用的各个请求共享组件。它的 `entities` 选项会追加到连接选项的实体中。
|
|
255
|
-
|
|
256
|
-
```typescript
|
|
257
|
-
import {Application} from 'lakutata'
|
|
258
|
-
import {buildDatabaseOptions, Database} from 'lakutata/provider/database'
|
|
259
|
-
|
|
260
|
-
Application
|
|
261
|
-
.run(() => ({
|
|
262
|
-
id: 'com.example.reports',
|
|
263
|
-
name: 'Reports',
|
|
264
|
-
providers: {
|
|
265
|
-
reports: {
|
|
266
|
-
...buildDatabaseOptions({type: 'postgres', url: process.env.REPORTS_URL}),
|
|
267
|
-
entities: [Report]
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}))
|
|
271
|
-
.onLaunched(async (app: Application): Promise<void> => {
|
|
272
|
-
//在这里打开连接,随应用一起关闭
|
|
273
|
-
const database: Database = await app.getObject<Database>('reports')
|
|
274
|
-
console.log(await database.getRepository(Report).count())
|
|
275
|
-
})
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
## 7. 多个数据库
|
|
279
|
-
|
|
280
|
-
每个数据库是一个有自己名称的组件,按该名称注入:
|
|
281
|
-
|
|
282
|
-
```typescript
|
|
283
|
-
Application.run(() => ({
|
|
284
|
-
id: 'com.example.shop',
|
|
285
|
-
name: 'Shop',
|
|
286
|
-
components: {
|
|
287
|
-
db: buildDatabaseOptions({type: 'postgres', url: process.env.DATABASE_URL, entities: [User, Order, OrderLine]}),
|
|
288
|
-
analytics: buildDatabaseOptions({type: 'mysql', url: process.env.ANALYTICS_URL, entities: [Visit]})
|
|
289
|
-
},
|
|
290
|
-
bootstrap: ['db', 'analytics']
|
|
291
|
-
}))
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
## 8. 迁移
|
|
295
|
-
|
|
296
|
-
迁移是实现了 `MigrationInterface`(来自 `lakutata/orm`)的类:`up()` 修改表结构,`down()` 撤销修改。连接选项 `migrations` 列出所有迁移。迁移在以下情况下执行:连接时设置了 `migrationsRun: true`,调用组件或提供者的 `runMigrations()` 和 `undoLastMigration()`,或者通过应用的迁移命令。
|
|
297
|
-
|
|
298
|
-
迁移命令是传给应用本身的环境变量:带着其中一个变量启动时,应用读取自己的选项,然后不执行 `bootstrap` 和 `onLaunched` 处理函数,而是对选项中的每个 `Database` 组件和提供者执行该命令,然后退出(成功时退出码为 0,失败时为 1)。
|
|
299
|
-
|
|
300
|
-
| 变量 | 命令 |
|
|
301
|
-
|---|---|
|
|
302
|
-
| `MIGRATION_GENERATE=<directory>` | 比较实体和数据库表结构,把差异的 SQL 作为迁移写入该目录 |
|
|
303
|
-
| `MIGRATION_RUN=1` | 执行待执行的迁移 |
|
|
304
|
-
| `MIGRATION_REVERT=1` | 撤销最后一次执行的迁移(有多个数据库时必须指定 `MIGRATION_DATABASE`) |
|
|
305
|
-
| `MIGRATION_SHOW=1` | 列出已执行和待执行的迁移 |
|
|
306
|
-
| `MIGRATION_DATABASE=<name>` | 命令作用的数据库(默认全部) |
|
|
307
|
-
| `MIGRATION_TRANSACTION=all\|each\|none` | `MIGRATION_RUN` 和 `MIGRATION_REVERT` 的事务方式 |
|
|
308
|
-
| `MIGRATION_FAKE=1` | 只把迁移记录为已执行(或已撤销),不真正执行 |
|
|
309
|
-
|
|
310
|
-
```shell
|
|
311
|
-
MIGRATION_GENERATE=src/migrations node dist/App.js
|
|
312
|
-
MIGRATION_RUN=1 node dist/App.js
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
## 9. 注意事项
|
|
316
|
-
|
|
317
|
-
- 生产环境中把 `synchronize` 设为 `false`,用迁移修改表结构。
|
|
318
|
-
- `pg` 把 `numeric` 和 `bigint` 列读成字符串:用列的 `transformer` 进行转换。
|
|
319
|
-
- 错误类型是 TypeORM 的错误,由 `lakutata/orm` 导出:`QueryFailedError`(其 `driverError` 包含驱动的错误)、`EntityNotFoundError`(`findOneByOrFail()`)、`EntityMetadataNotFoundError`(实体不在连接的 `entities` 中)等。
|