mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
docs: spelling and general improvements (part 4)
This commit is contained in:
parent
8714a84e01
commit
bf18b05fae
@ -19,15 +19,15 @@
|
||||
* [`@JoinColumn`](#joincolumn)
|
||||
* [`@JoinTable`](#jointable)
|
||||
* [`@RelationId`](#relationid)
|
||||
* [Subscriber and listener decorators](#subscriber-and-listener-decorators)
|
||||
* [`@AfterLoad`](#afterload)
|
||||
* [`@BeforeInsert`](#beforeinsert)
|
||||
* [`@AfterInsert`](#afterinsert)
|
||||
* [`@BeforeUpdate`](#beforeupdate)
|
||||
* [`@AfterUpdate`](#afterupdate)
|
||||
* [`@BeforeRemove`](#beforeremove)
|
||||
* [`@AfterRemove`](#afterremove)
|
||||
* [`@EventSubscriber`](#eventsubscriber)
|
||||
* [Subscriber and listener decorators](./listeners-and-subscribers.md)
|
||||
* [`@AfterLoad`](./listeners-and-subscribers.md#afterload)
|
||||
* [`@BeforeInsert`](./listeners-and-subscribers.md#beforeinsert)
|
||||
* [`@AfterInsert`](./listeners-and-subscribers.md#afterinsert)
|
||||
* [`@BeforeUpdate`](./listeners-and-subscribers.md#beforeupdate)
|
||||
* [`@AfterUpdate`](./listeners-and-subscribers.md#afterupdate)
|
||||
* [`@BeforeRemove`](./listeners-and-subscribers.md#beforeremove)
|
||||
* [`@AfterRemove`](./listeners-and-subscribers.md#afterremove)
|
||||
* [`@EventSubscriber`](./listeners-and-subscribers.md#what-is-a-subscriber)
|
||||
* [Other decorators](#other-decorators)
|
||||
* [`@Index`](#index)
|
||||
* [`@Transaction`, `@TransactionManager` and `@TransactionRepository`](#transaction-transactionmanager-and-transactionrepository)
|
||||
@ -284,7 +284,7 @@ export class User {
|
||||
}
|
||||
```
|
||||
|
||||
Learn more about [one-to-one relations](./relations.md#one-to-one-relations).
|
||||
Learn more about [one-to-one relations](./one-to-one-relations.md).
|
||||
|
||||
#### `@ManyToOne`
|
||||
|
||||
@ -312,7 +312,7 @@ export class Photo {
|
||||
}
|
||||
```
|
||||
|
||||
Learn more about [many-to-one / one-to-many relations](./relations.md#many-to-one-one-to-many-relations).
|
||||
Learn more about [many-to-one / one-to-many relations](./many-to-one-one-to-many-relations.md).
|
||||
|
||||
#### `@OneToMany`
|
||||
|
||||
@ -340,7 +340,7 @@ export class User {
|
||||
}
|
||||
```
|
||||
|
||||
Learn more about [many-to-one / one-to-many relations](./relations.md#many-to-one-one-to-many-relations).
|
||||
Learn more about [many-to-one / one-to-many relations](./many-to-one-one-to-many-relations.md).
|
||||
|
||||
#### `@ManyToMany`
|
||||
|
||||
@ -372,7 +372,7 @@ export class Question {
|
||||
}
|
||||
```
|
||||
|
||||
Learn more about [many-to-many relations](./relations.md#many-to-one-one-to-many-relations).
|
||||
Learn more about [many-to-many relations](./many-to-many-relations.md).
|
||||
|
||||
#### `@JoinColumn`
|
||||
|
||||
@ -463,189 +463,6 @@ export class Post {
|
||||
Relation id is used only for representation.
|
||||
The underlying relation is not added/removed/changed when chaning the value.
|
||||
|
||||
## Subscriber and listener decorators
|
||||
|
||||
#### `@AfterLoad`
|
||||
|
||||
You can define a method with any name in entity and mark it with `@AfterLoad`
|
||||
and TypeORM will call it each time the entity
|
||||
is loaded using `QueryBuilder` or repository/manager find methods.
|
||||
Example:
|
||||
|
||||
```typescript
|
||||
@Entity()
|
||||
export class Post {
|
||||
|
||||
@AfterLoad()
|
||||
updateCounters() {
|
||||
if (this.likesCount === undefined)
|
||||
this.likesCount = 0;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Learn more about [listeners](listeners-and-subscribers.md).
|
||||
|
||||
#### `@BeforeInsert`
|
||||
|
||||
You can define a method with any name in entity and mark it with `@BeforeInsert`
|
||||
and TypeORM will call it before the entity is inserted using repository/manager `save`.
|
||||
Example:
|
||||
|
||||
```typescript
|
||||
@Entity()
|
||||
export class Post {
|
||||
|
||||
@BeforeInsert()
|
||||
updateDates() {
|
||||
this.createdDate = new Date();
|
||||
}
|
||||
}
|
||||
```
|
||||
Learn more about [listeners](listeners-and-subscribers.md).
|
||||
|
||||
#### `@AfterInsert`
|
||||
|
||||
You can define a method with any name in entity and mark it with `@AfterInsert`
|
||||
and TypeORM will call it after the entity is inserted using repository/manager `save`.
|
||||
Example:
|
||||
|
||||
```typescript
|
||||
@Entity()
|
||||
export class Post {
|
||||
|
||||
@AfterInsert()
|
||||
resetCounters() {
|
||||
this.counters = 0;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Learn more about [listeners](listeners-and-subscribers.md).
|
||||
|
||||
#### `@BeforeUpdate`
|
||||
|
||||
You can define a method with any name in the entity and mark it with `@BeforeUpdate`
|
||||
and TypeORM will call it before an existing entity is updated using repository/manager `save`.
|
||||
Example:
|
||||
|
||||
```typescript
|
||||
@Entity()
|
||||
export class Post {
|
||||
|
||||
@BeforeUpdate()
|
||||
updateDates() {
|
||||
this.updatedDate = new Date();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Learn more about [listeners](listeners-and-subscribers.md).
|
||||
|
||||
#### `@AfterUpdate`
|
||||
|
||||
You can define a method with any name in the entity and mark it with `@AfterUpdate`
|
||||
and TypeORM will call it after an existing entity is updated using repository/manager `save`.
|
||||
Example:
|
||||
|
||||
```typescript
|
||||
@Entity()
|
||||
export class Post {
|
||||
|
||||
@AfterUpdate()
|
||||
updateCounters() {
|
||||
this.counter = 0;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Learn more about [listeners](listeners-and-subscribers.md).
|
||||
|
||||
#### `@BeforeRemove`
|
||||
|
||||
You can define a method with any name in the entity and mark it with `@BeforeRemove`
|
||||
and TypeORM will call it before a entity is removed using repository/manager `remove`.
|
||||
Example:
|
||||
|
||||
```typescript
|
||||
@Entity()
|
||||
export class Post {
|
||||
|
||||
@BeforeRemove()
|
||||
updateStatus() {
|
||||
this.status = "removed";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Learn more about [listeners](listeners-and-subscribers.md).
|
||||
|
||||
#### `@AfterRemove`
|
||||
|
||||
You can define a method with any name in the entity and mark it with `@AfterRemove`
|
||||
and TypeORM will call it after the entity is removed using repository/manager `remove`.
|
||||
Example:
|
||||
|
||||
```typescript
|
||||
@Entity()
|
||||
export class Post {
|
||||
|
||||
@AfterRemove()
|
||||
updateStatus() {
|
||||
this.status = "removed";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Learn more about [listeners](listeners-and-subscribers.md).
|
||||
|
||||
#### `@EventSubscriber`
|
||||
|
||||
Marks a class as an event subscriber which can listen to specific entity events or any entity events.
|
||||
Events are firing using `QueryBuilder` and repository/manager methods.
|
||||
Example:
|
||||
|
||||
```typescript
|
||||
@EventSubscriber()
|
||||
export class PostSubscriber implements EntitySubscriberInterface<Post> {
|
||||
|
||||
|
||||
/**
|
||||
* Indicates that this subscriber only listen to Post events.
|
||||
*/
|
||||
listenTo() {
|
||||
return Post;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called before post insertion.
|
||||
*/
|
||||
beforeInsert(event: InsertEvent<Post>) {
|
||||
console.log(`BEFORE POST INSERTED: `, event.entity);
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
You can implement any method from `EntitySubscriberInterface`.
|
||||
To listen to any entity you just omit `listenTo` method and use `any`:
|
||||
|
||||
```typescript
|
||||
@EventSubscriber()
|
||||
export class PostSubscriber implements EntitySubscriberInterface {
|
||||
|
||||
/**
|
||||
* Called before entity insertion.
|
||||
*/
|
||||
beforeInsert(event: InsertEvent<any>) {
|
||||
console.log(`BEFORE ENTITY INSERTED: `, event.entity);
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Learn more about [subscribers](listeners-and-subscribers.md).
|
||||
|
||||
## Other decorators
|
||||
|
||||
#### `@Index`
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
## Column indices
|
||||
|
||||
You can create a database index for a specific column by using `@Index` decorator on a column you want to make an index.
|
||||
You can create a database index for a specific column by using `@Index` on a column you want to make an index.
|
||||
You can create indices for any columns of your entity.
|
||||
Example:
|
||||
|
||||
@ -29,7 +29,7 @@ export class User {
|
||||
}
|
||||
```
|
||||
|
||||
You can also specify index name:
|
||||
You can also specify an index name:
|
||||
|
||||
```typescript
|
||||
import {Entity, PrimaryGeneratedColumn, Column, Index} from "typeorm";
|
||||
@ -52,7 +52,7 @@ export class User {
|
||||
|
||||
## Unique indices
|
||||
|
||||
To create unique index you need to specify `{ unique: true }` in index options:
|
||||
To create an unique index you need to specify `{ unique: true }` in the index options:
|
||||
|
||||
```typescript
|
||||
import {Entity, PrimaryGeneratedColumn, Column, Index} from "typeorm";
|
||||
@ -75,7 +75,7 @@ export class User {
|
||||
|
||||
## Indices with multiple columns
|
||||
|
||||
To create index with multiple columns you need to put `@Index` decorator on entity itself
|
||||
To create an index with multiple columns you need to put `@Index` on the entity itself
|
||||
and specify all column property names which should be included in the index.
|
||||
Example:
|
||||
|
||||
|
||||
@ -17,6 +17,6 @@ await getConnection()
|
||||
.execute();
|
||||
```
|
||||
|
||||
This is the most efficient in terms of performance way to insert things into your database.
|
||||
You can also perform bulky insertions this way.
|
||||
This is the most efficient way in terms of performance to insert rows into your database.
|
||||
You can also perform bulk insertions this way.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# Entity Listeners and Subscribers
|
||||
|
||||
* [What is Entity Listener](#what-is-entity-listener)
|
||||
* [What is an Entity Listener](#what-is-an-entity-listener)
|
||||
* [`@AfterLoad`](#afterload)
|
||||
* [`@BeforeInsert`](#beforeinsert)
|
||||
* [`@AfterInsert`](#afterinsert)
|
||||
@ -8,17 +8,17 @@
|
||||
* [`@AfterUpdate`](#afterupdate)
|
||||
* [`@BeforeRemove`](#beforeremove)
|
||||
* [`@AfterRemove`](#afterremove)
|
||||
* [What is Subscriber](#what-is-subscriber)
|
||||
* [What is a Subscriber](#what-is-a-subscriber)
|
||||
|
||||
## What is Entity Listener
|
||||
## What is an Entity Listener
|
||||
|
||||
Any your entity can have methods with custom logic that listen to specific entity events.
|
||||
You must mark those methods with special decorators depend on what event you want listen to.
|
||||
Any of your entities can have methods with custom logic that listen to specific entity events.
|
||||
You must mark those methods with special decorators depending on what event you want to listen to.
|
||||
|
||||
### `@AfterLoad`
|
||||
|
||||
You can define method with any name in entity and mark it with `@AfterLoad` decorator
|
||||
and orm will call this method each time entity
|
||||
You can define a method with any name in entity and mark it with `@AfterLoad`
|
||||
and TypeORM will call it each time the entity
|
||||
is loaded using `QueryBuilder` or repository/manager find methods.
|
||||
Example:
|
||||
|
||||
@ -36,8 +36,8 @@ export class Post {
|
||||
|
||||
### `@BeforeInsert`
|
||||
|
||||
You can define method with any name in entity and mark it with `@BeforeInsert` decorator
|
||||
and orm will call this method before entity inserted into the database using repository/manager `save` method.
|
||||
You can define a method with any name in entity and mark it with `@BeforeInsert`
|
||||
and TypeORM will call it before the entity is inserted using repository/manager `save`.
|
||||
Example:
|
||||
|
||||
```typescript
|
||||
@ -53,8 +53,8 @@ export class Post {
|
||||
|
||||
### `@AfterInsert`
|
||||
|
||||
You can define method with any name in entity and mark it with `@AfterInsert` decorator
|
||||
and orm will call this method after entity inserted into the database using repository/manager `save` method.
|
||||
You can define a method with any name in entity and mark it with `@AfterInsert`
|
||||
and TypeORM will call it after the entity is inserted using repository/manager `save`.
|
||||
Example:
|
||||
|
||||
```typescript
|
||||
@ -70,8 +70,8 @@ export class Post {
|
||||
|
||||
### `@BeforeUpdate`
|
||||
|
||||
You can define method with any name in entity and mark it with `@BeforeUpdate` decorator
|
||||
and orm will call this method before exist entity is updated in the database using repository/manager `save` method.
|
||||
You can define a method with any name in the entity and mark it with `@BeforeUpdate`
|
||||
and TypeORM will call it before an existing entity is updated using repository/manager `save`.
|
||||
Example:
|
||||
|
||||
```typescript
|
||||
@ -87,8 +87,8 @@ export class Post {
|
||||
|
||||
### `@AfterUpdate`
|
||||
|
||||
You can define method with any name in entity and mark it with `@AfterUpdate` decorator
|
||||
and orm will call this method after exist entity is updated in the database using repository/manager `save` method.
|
||||
You can define a method with any name in the entity and mark it with `@AfterUpdate`
|
||||
and TypeORM will call it after an existing entity is updated using repository/manager `save`.
|
||||
Example:
|
||||
|
||||
```typescript
|
||||
@ -104,8 +104,8 @@ export class Post {
|
||||
|
||||
### `@BeforeRemove`
|
||||
|
||||
You can define method with any name in entity and mark it with `@BeforeRemove` decorator
|
||||
and orm will call this method before entity is removed from the database using repository/manager `remove` method.
|
||||
You can define a method with any name in the entity and mark it with `@BeforeRemove`
|
||||
and TypeORM will call it before a entity is removed using repository/manager `remove`.
|
||||
Example:
|
||||
|
||||
```typescript
|
||||
@ -121,8 +121,8 @@ export class Post {
|
||||
|
||||
### `@AfterRemove`
|
||||
|
||||
You can define method with any name in entity and mark it with `@AfterRemove` decorator
|
||||
and orm will call this method after entity is removed from the database using repository/manager `remove` method.
|
||||
You can define a method with any name in the entity and mark it with `@AfterRemove`
|
||||
and TypeORM will call it after the entity is removed using repository/manager `remove`.
|
||||
Example:
|
||||
|
||||
```typescript
|
||||
@ -136,10 +136,10 @@ export class Post {
|
||||
}
|
||||
```
|
||||
|
||||
## What is Subscriber
|
||||
## What is a Subscriber
|
||||
|
||||
You can create separate event subscriber classes which can listen to specific entity events or any entity events.
|
||||
Events are firing using `QueryBuilder` or repository/manager methods.
|
||||
Marks a class as an event subscriber which can listen to specific entity events or any entity events.
|
||||
Events are firing using `QueryBuilder` and repository/manager methods.
|
||||
Example:
|
||||
|
||||
```typescript
|
||||
@ -164,7 +164,7 @@ export class PostSubscriber implements EntitySubscriberInterface<Post> {
|
||||
}
|
||||
```
|
||||
|
||||
You can implement any method from `EntitySubscriberInterface` interface.
|
||||
You can implement any method from `EntitySubscriberInterface`.
|
||||
To listen to any entity you just omit `listenTo` method and use `any`:
|
||||
|
||||
```typescript
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
## Enabling logging
|
||||
|
||||
You can enable all queries logging by simply setting `logging: true` in your connection options:
|
||||
You can enable logging of all queries and errors by simply setting `logging: true` in your connection options:
|
||||
|
||||
```typescript
|
||||
{
|
||||
@ -24,8 +24,6 @@ You can enable all queries logging by simply setting `logging: true` in your con
|
||||
}
|
||||
```
|
||||
|
||||
This configuration will enable all executed queries logging and failed query errors.
|
||||
|
||||
## Logging options
|
||||
|
||||
You can enable different types of logging in connection options:
|
||||
@ -38,7 +36,7 @@ You can enable different types of logging in connection options:
|
||||
}
|
||||
```
|
||||
|
||||
If you want to enable only logging of failed queries then only enable `error` in configuration:
|
||||
If you want to enable logging of failed queries only then only add `error`:
|
||||
|
||||
```typescript
|
||||
{
|
||||
@ -48,16 +46,16 @@ If you want to enable only logging of failed queries then only enable `error` in
|
||||
}
|
||||
```
|
||||
|
||||
There are few other options you can use:
|
||||
There are other options you can use:
|
||||
|
||||
* `query` - enables all query logging
|
||||
* `error` - enables failed query error logging
|
||||
* `schema` - enables schema build process logging
|
||||
* `warn` - enables internal orm warning messages logging
|
||||
* `info` - enables internal orm informative messages logging
|
||||
* `log` - enables internal orm log messages logging
|
||||
* `query` - log all queries
|
||||
* `error` - log all failed queries and error
|
||||
* `schema` - log the schema build process
|
||||
* `warn` - log internal orm warnings
|
||||
* `info` - log internal orm informative messages
|
||||
* `log` - log internal orm log messages
|
||||
|
||||
You can specify as many of logging options as needed.
|
||||
You can specify as many options as needed.
|
||||
If you want to enable all logging you can simply specify `logging: "all"`:
|
||||
|
||||
```typescript
|
||||
@ -70,8 +68,8 @@ If you want to enable all logging you can simply specify `logging: "all"`:
|
||||
|
||||
## Log long-running queries
|
||||
|
||||
If you have performance issues you can log queries that execute too much time
|
||||
by setting `maxQueryExecutionTime` option in connection options:
|
||||
If you have performance issues you can log queries that take too much time to execute
|
||||
by setting `maxQueryExecutionTime` in connection options:
|
||||
|
||||
```typescript
|
||||
{
|
||||
@ -85,15 +83,15 @@ This code will log all queries which run more then `1 second`.
|
||||
|
||||
## Changing default logger
|
||||
|
||||
There are several loggers TypeORM ships with 3 different types of loggers:
|
||||
TypeORM ships with 3 different types of logger:
|
||||
|
||||
* `advanced-console` - this is default logger which logs all messages into console using color
|
||||
and sql syntax highlighting (using [chalk](https://github.com/chalk/chalk) package)
|
||||
* `simple-console` - this is simple console logger which is exactly the same as advanced, but it does not use any color highlighting.
|
||||
* `advanced-console` - this is default which logs all messages onto the console using color
|
||||
and sql syntax highlighting (using [chalk](https://github.com/chalk/chalk))
|
||||
* `simple-console` - this is a simple console logger which is exactly the same as the advanced logger, but it does not use any color highlighting.
|
||||
This logger can be used if you have problems / or don't like colorized logs
|
||||
* `file` - this logger writes all logs into `ormlogs.log` file in the root folder of your project (near `package.json` and `ormconfig.json`)
|
||||
* `file` - this logger writes all logs into `ormlogs.log` in the root folder of your project (near `package.json` and `ormconfig.json`)
|
||||
|
||||
You can enable any of them in connection options this way:
|
||||
You can enable any of them in connection options:
|
||||
|
||||
```typescript
|
||||
{
|
||||
@ -106,8 +104,7 @@ You can enable any of them in connection options this way:
|
||||
|
||||
## Using custom logger
|
||||
|
||||
You can create your own logger class by implementing `Logger` interface and
|
||||
specifying your custom logger in connection options:
|
||||
You can create your own logger class by implementing the `Logger` interface:
|
||||
|
||||
```typescript
|
||||
import {Logger} from "typeorm";
|
||||
|
||||
@ -42,8 +42,8 @@ export class Question {
|
||||
}
|
||||
```
|
||||
|
||||
`@JoinTable()` decorator is required for `@ManyToMany` relations.
|
||||
You must put `@JoinTable` decorator only from one (owning) side of relation.
|
||||
`@JoinTable()` is required for `@ManyToMany` relations.
|
||||
You must put `@JoinTable` on one (owning) side of relation.
|
||||
|
||||
This example will produce following tables:
|
||||
|
||||
@ -105,10 +105,10 @@ const questions = await connection
|
||||
.getMany();
|
||||
```
|
||||
|
||||
With eager loading enabled on a relation you don't have to specify relation or join it - it will be loaded automatically ALWAYS.
|
||||
With eager loading enabled on a relation you don't have to specify relation or join it - it will ALWAYS be loaded automatically.
|
||||
|
||||
Relations can be uni-directional and bi-directional.
|
||||
Uni-directional are relations with relation decorator only on one side.
|
||||
Uni-directional are relations with a relation decorator only on one side.
|
||||
Bi-directional are relations with decorators on both sides of a relation.
|
||||
|
||||
We just created a uni-directional relation. Let's make it bi-directional:
|
||||
@ -155,8 +155,8 @@ export class Question {
|
||||
}
|
||||
```
|
||||
|
||||
We just made our relation bi-directional. Note, inverse relation does not have a `@JoinTable` decorator.
|
||||
`@JoinTable` must be only on one side of the relation - which table will own a foreign key.
|
||||
We just made our relation bi-directional. Note, the inverse relation does not have a `@JoinTable`.
|
||||
`@JoinTable` must be only on one side of the relation.
|
||||
|
||||
Bi-directional relations allow you to join relations from both sides using `QueryBuilder`:
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
Many-to-one / one-to-many is a relation where A contains multiple instances of B, but B contains only one instance of A.
|
||||
Let's take for example `User` and `Photo` entities.
|
||||
User can have multiple photos, but each photo is owned only by a single user.
|
||||
User can have multiple photos, but each photo is owned by only one single user.
|
||||
|
||||
```typescript
|
||||
import {Entity, PrimaryGeneratedColumn, Column, ManyToOne} from "typeorm";
|
||||
@ -42,11 +42,11 @@ export class User {
|
||||
}
|
||||
```
|
||||
|
||||
Here we added `@ManyToOne` decorator to the `photos` property and specified target relation type `Photo` to it.
|
||||
You can omit `@JoinColumn` decorator in case of `@ManyToOne` / `@OneToMany` relation.
|
||||
`@OneToMany` decorator cannot exist without `@ManyToOne` decorator.
|
||||
If you want to use `@OneToMany` decorator `@ManyToOne` is required.
|
||||
Where you set `@ManyToOne` decorator - its related entity will have "relation id" and foreign key.
|
||||
Here we added `@ManyToOne` to the `photos` property and specified the target relation type to be `Photo`.
|
||||
You can omit `@JoinColumn` in a `@ManyToOne` / `@OneToMany` relation.
|
||||
`@OneToMany` cannot exist without `@ManyToOne`.
|
||||
If you want to use `@OneToMany`, `@ManyToOne` is required.
|
||||
Where you set `@ManyToOne` - its related entity will have "relation id" and foreign key.
|
||||
|
||||
This example will produce following tables:
|
||||
|
||||
@ -102,7 +102,7 @@ await connection.manager.save(photo2);
|
||||
|
||||
With cascades enabled you can save this relation with only one `save` call.
|
||||
|
||||
To load user with photos inside you must specify relation in `FindOptions`:
|
||||
To load a user with photos inside you must specify the relation in `FindOptions`:
|
||||
|
||||
```typescript
|
||||
const userRepository = connection.getRepository(User);
|
||||
@ -132,4 +132,4 @@ const photos = await connection
|
||||
.getMany();
|
||||
```
|
||||
|
||||
With eager loading enabled on a relation you don't have to specify relation or join it - it will be loaded automatically ALWAYS.
|
||||
With eager loading enabled on a relation you don't have to specify relation or join it - it will ALWAYS be loaded automatically.
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
# Migrations
|
||||
|
||||
* [How migrations are working](#how-migrations-are-working)
|
||||
* [How migrations work](#how-migrations-work)
|
||||
* [Creating a new migration](#creating-a-new-migration)
|
||||
* [Running and reverting migrations](#running-and-reverting-migrations)
|
||||
* [Generating migrations](#generating-migrations)
|
||||
* [Using migration API to write migrations](#using-migration-api-to-write-migrations)
|
||||
|
||||
## How migrations are working
|
||||
## How migrations work
|
||||
|
||||
Once you get into the production you'll need to synchronize model changes into the database.
|
||||
Once you get into production you'll need to synchronize model changes into the database.
|
||||
Typically it is unsafe to use `synchronize: true` for schema synchronization on production once
|
||||
you get data in your database. Here is where migrations come to help.
|
||||
|
||||
Migration is just a single file with sql queries written by you to update a database schema
|
||||
and apply a new changes to exist database.
|
||||
A migration is just a single file with sql queries to update a database schema
|
||||
and apply new changes to an exist database.
|
||||
|
||||
Let's say you already have a database and a post entity:
|
||||
|
||||
@ -33,20 +33,20 @@ export class Post {
|
||||
}
|
||||
```
|
||||
|
||||
And your entity worked in production for month without any changes.
|
||||
And your entity worked in production for months without any changes.
|
||||
You have thousands posts in your database.
|
||||
|
||||
Now you need to make a new release and rename `title` column to `name`.
|
||||
Now you need to make a new release and rename `title` to `name`.
|
||||
What would you do?
|
||||
|
||||
You need to create a new migration and put there following sql query (postgres dialect):
|
||||
You need to create a new migration with the following sql query (postgres dialect):
|
||||
|
||||
```sql
|
||||
ALTER TABLE "post" ALTER COLUMN "title" RENAME TO "name";
|
||||
```
|
||||
|
||||
Once you run this sql query your database schema is ready to work with new codebase.
|
||||
TypeORM provides you a place where you can write such sql queries and run them when needed.
|
||||
Once you run this sql query your database schema is ready to work with your new codebase.
|
||||
TypeORM provides a place where you can write such sql queries and run them when needed.
|
||||
This place is called "migrations".
|
||||
|
||||
## Creating a new migration
|
||||
@ -72,7 +72,7 @@ Before creating a new migration you need to setup your connection options proper
|
||||
Here we setup two options:
|
||||
|
||||
* `"migrations": ["migration/*.js"]` - indicates that typeorm must load migrations from the given "migration" directory
|
||||
* `"cli": { "migrationsDir": "migration" }` - indicates that CLI must create new migrations in the "migration" directory
|
||||
* `"cli": { "migrationsDir": "migration" }` - indicates that the CLI must create new migrations in the "migration" directory
|
||||
|
||||
Once you setup connection options you can create a new migration using CLI:
|
||||
|
||||
@ -81,15 +81,15 @@ typeorm migrations:create -n PostRefactoring
|
||||
```
|
||||
|
||||
To use CLI commands you need to install typeorm globally (`npm i typeorm -g`).
|
||||
Also make sure your locally typeorm version matches globally installed.
|
||||
For more information about typeorm CLI read documentation [here](./using-cli.md).
|
||||
Also make sure your locally typeorm version matches the global version.
|
||||
Learn more about the [TypeORM CLI](./using-cli.md).
|
||||
|
||||
Here, `PostRefactoring` is the name of migration - you can specify any name you want.
|
||||
After you run this command you can see a new file generated in "migration" directory,
|
||||
named `{TIMESTAMP}-PostRefactoring.ts` where `{TIMESTAMP}` is current timestamp when migration was generated.
|
||||
Now you can open this file and add your migration sql queries there.
|
||||
Here, `PostRefactoring` is the name of the migration - you can specify any name you want.
|
||||
After you run the command you can see a new file generated in "migration" directory,
|
||||
named `{TIMESTAMP}-PostRefactoring.ts` where `{TIMESTAMP}` is the current timestamp when the migration was generated.
|
||||
Now you can open the file and add your migration sql queries there.
|
||||
|
||||
You should see following content inside your migration:
|
||||
You should see the following content inside your migration:
|
||||
|
||||
```typescript
|
||||
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||
@ -109,15 +109,15 @@ export class PostRefactoringTIMESTAMP implements MigrationInterface {
|
||||
```
|
||||
|
||||
There are two methods you must fill with your migration code: `up` and `down`.
|
||||
In `up` method you must write all the code you need to perform migration.
|
||||
In `down` method you must write all the code that reverts things made in `up` method.
|
||||
`down` method is used when you screw things up and want to revert last migration.
|
||||
`up` has to contain the code you need to perform the migration.
|
||||
`down` has to revert whatever `up` changed.
|
||||
`down` method is used to revert the last migration.
|
||||
|
||||
Inside both `up` and `down` methods you have a `QueryRunner` object.
|
||||
Inside both `up` and `down` you have a `QueryRunner` object.
|
||||
All database operations are executing using this object.
|
||||
For more infromation about query runner see [this documentation](./query-runner.md).
|
||||
Learn more about [query runner](./query-runner.md).
|
||||
|
||||
Let's see how this migration will look like with our `Post` changes requirement:
|
||||
Let's see what the migration looks like with our `Post` changes:
|
||||
|
||||
```typescript
|
||||
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||
@ -138,30 +138,30 @@ export class PostRefactoringTIMESTAMP implements MigrationInterface {
|
||||
|
||||
## Running and reverting migrations
|
||||
|
||||
Once you have a migration to run on production you can run the using CLI command:
|
||||
Once you have a migration to run on production you can run them using a CLI command:
|
||||
|
||||
```
|
||||
typeorm migrations:run
|
||||
```
|
||||
|
||||
This command will execute all pending migrations and run them in a sequence ordered by their timestamps.
|
||||
It means all sql queries you wrote in `up` methods of your created migrations will be executed.
|
||||
This means all sql queries written in the `up` methods of your created migrations will be executed.
|
||||
That's all! Now you have your database schema up-to-date.
|
||||
|
||||
If for some reason you screw things up you can revert last executed migration using CLI command:
|
||||
If for some reason you want to revert the changes, you can run:
|
||||
|
||||
```
|
||||
typeorm migrations:revert
|
||||
```
|
||||
|
||||
This command will execute `down` method in the latest executed migration.
|
||||
If you need to revert more you must call this command again and again, as much as needed to revert.
|
||||
This command will execute `down` in the latest executed migration.
|
||||
If you need to revert multiple migrations you must call this command multiple times.
|
||||
|
||||
## Generating migrations
|
||||
|
||||
TypeORM is able to automatically generate migration files with schema changes you made inside it.
|
||||
TypeORM is able to automatically generate migration files with schema changes you made.
|
||||
|
||||
Let's say you have `Post` entity with `title` column. And you have changed `title` column name to `name`.
|
||||
Let's say you have a `Post` entity with a `title` column. And you have changed the name `title` to `name`.
|
||||
You can run following command:
|
||||
|
||||
```
|
||||
@ -187,8 +187,8 @@ export class PostRefactoringTIMESTAMP implements MigrationInterface {
|
||||
}
|
||||
```
|
||||
|
||||
See, you don't need to write such queries on your own.
|
||||
The rule of thumb of generated migrations is that you generate them after "each" change you made to your models.
|
||||
See, you don't need to write the queries on your own.
|
||||
The rule of thumb for generating migrations is that you generate them after "each" change you made to your models.
|
||||
|
||||
## Using migration API to write migrations
|
||||
|
||||
|
||||
@ -13,9 +13,9 @@ this page contains all MongoDB-specific functionality documentation.
|
||||
|
||||
## Defining entities and columns
|
||||
|
||||
Defining entities and columns almost same as in relational databases,
|
||||
the main difference is that you must use `@ObjectIdColumn` decorator
|
||||
instead of `@PrimaryColumn` or `@PrimaryGeneratedColumn` decorators.
|
||||
Defining entities and columns is almost the same as in relational databases,
|
||||
the main difference is that you must use `@ObjectIdColumn`
|
||||
instead of `@PrimaryColumn` or `@PrimaryGeneratedColumn`.
|
||||
|
||||
Simple entity example:
|
||||
|
||||
@ -53,7 +53,7 @@ const connection: Connection = await createConnection({
|
||||
## Defining subdocuments (embed documents)
|
||||
|
||||
Since MongoDB stores objects and objects inside objects (or documents inside documents)
|
||||
you can do same in TypeORM this way:
|
||||
you can do the same in TypeORM:
|
||||
|
||||
```typescript
|
||||
import {Entity, ObjectID, ObjectIdColumn, Column} from "typeorm";
|
||||
@ -168,7 +168,7 @@ Following document will be saved in the database:
|
||||
|
||||
## Using `MongoEntityManager` and `MongoRepository`
|
||||
|
||||
You can use most of `EntityManager` methods (except for RDBMS-specific, like `query` and `transaction`).
|
||||
You can use the majority of methods inside the `EntityManager` (except for RDBMS-specific, like `query` and `transaction`).
|
||||
For example:
|
||||
|
||||
```typescript
|
||||
@ -178,7 +178,7 @@ const manager = getManager(); // or connection.manager
|
||||
const timber = await manager.findOne(User, { firstName: "Timber", lastName: "Saw" });
|
||||
```
|
||||
|
||||
For MongoDB there is also separate `MongoEntityManager` which extends `EntityManager` functionality.
|
||||
For MongoDB there is also a separate `MongoEntityManager` which extends `EntityManager`.
|
||||
|
||||
```typescript
|
||||
import {getMongoManager} from "typeorm";
|
||||
@ -187,7 +187,7 @@ const manager = getMongoManager(); // or connection.mongoManager
|
||||
const timber = await manager.findOne(User, { firstName: "Timber", lastName: "Saw" });
|
||||
```
|
||||
|
||||
Just like separate `MongoEntityManager` there is `MongoRepository` with extended `Repository` functionality:
|
||||
Just like separate like `MongoEntityManager` there is a `MongoRepository` with extended `Repository`:
|
||||
|
||||
```typescript
|
||||
import {getMongoManager} from "typeorm";
|
||||
@ -206,7 +206,7 @@ Creates a cursor for a query that can be used to iterate over results from Mongo
|
||||
#### `createEntityCursor`
|
||||
|
||||
Creates a cursor for a query that can be used to iterate over results from MongoDB.
|
||||
This returns modified version of cursor that transforms each result into Entity model.
|
||||
This returns a modified version of the cursor that transforms each result into Entity models.
|
||||
|
||||
#### `aggregate`
|
||||
|
||||
@ -227,7 +227,7 @@ Creates an index on the db and collection.
|
||||
|
||||
#### `createCollectionIndexes`
|
||||
|
||||
Creates multiple indexes in the collection, this method is only supported for MongoDB 2.6 or higher.
|
||||
Creates multiple indexes in the collection, this method is only supported in MongoDB 2.6 or higher.
|
||||
|
||||
#### `deleteMany`
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
## Using multiple connections
|
||||
|
||||
The simplest way to use multiple databases is to create different multiple connections:
|
||||
The simplest way to use multiple databases is to create different connections:
|
||||
|
||||
```typescript
|
||||
import {createConnections} from "typeorm";
|
||||
@ -39,8 +39,8 @@ const connections = await createConnections([{
|
||||
This approach allows you to connect to any number of databases you have
|
||||
and each database will have its own configuration, own entities and overall ORM scope and settings.
|
||||
|
||||
For each connection new `Connection` instance will be created.
|
||||
You must specify unique name for each connection you create.
|
||||
For each connection a new `Connection` instance will be created.
|
||||
You must specify a unique name for each connection you create.
|
||||
|
||||
When working with connections you must specify a connection name to get a specific connection:
|
||||
|
||||
@ -56,7 +56,7 @@ const db2Connection = getConnection("db2Connection");
|
||||
|
||||
Benefit of using this approach is that you can configure multiple connections with different login credentials,
|
||||
host, port and even database type itself.
|
||||
Downside may be for you is that you'll need to manage and work with multiple connection instances.
|
||||
Downside for might be that you'll need to manage and work with multiple connection instances.
|
||||
|
||||
## Using multiple databases in a single connection
|
||||
|
||||
@ -119,7 +119,7 @@ SELECT * FROM "secondDB"."question" "question", "thirdDB"."photo" "photo"
|
||||
WHERE "photo"."userId" = "user"."id"
|
||||
```
|
||||
|
||||
You can also specify a table path instead of entity:
|
||||
You can also specify a table path instead of the entity:
|
||||
|
||||
```typescript
|
||||
const users = await connection
|
||||
@ -192,7 +192,7 @@ SELECT * FROM "secondSchema"."question" "question", "thirdSchema"."photo" "photo
|
||||
WHERE "photo"."userId" = "user"."id"
|
||||
```
|
||||
|
||||
You can also specify a table path instead of entity:
|
||||
You can also specify a table path instead of the entity:
|
||||
|
||||
```typescript
|
||||
const users = await connection
|
||||
@ -260,9 +260,9 @@ Example of replication connection settings:
|
||||
```
|
||||
|
||||
All schema update and write operations are performed using `master` server.
|
||||
All simple queries performed by using find methods or select query builder are using random `slave` instance.
|
||||
All simple queries performed by find methods or select query builder are using a random `slave` instance.
|
||||
|
||||
If you want explicitly use master in SELECT created by query builder, you can use following code:
|
||||
If you want to explicitly use master in SELECT created by query builder, you can use following code:
|
||||
|
||||
```typescript
|
||||
const postsFromMaster = await connection.createQueryBuilder(Post, "post")
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
## Creating your own `NamingStrategy`
|
||||
|
||||
If you defined your connection options in `ormconfig` file,
|
||||
If you defined your connection options in the `ormconfig` file,
|
||||
then you can simply use it and override it following way:
|
||||
|
||||
```typescript
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
One-to-one is a relation where A contains only once instance of B, and B contains only one instance of A.
|
||||
Let's take for example `User` and `Profile` entities.
|
||||
User can have only a single profile, and single profile is owned only by a single user.
|
||||
User can have only a single profile, and a single profile is owned by only a single user.
|
||||
|
||||
```typescript
|
||||
import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";
|
||||
@ -42,9 +42,9 @@ export class User {
|
||||
}
|
||||
```
|
||||
|
||||
Here we added `@OneToOne` decorator to the `profile` property and specified target relation type `Profile` to it.
|
||||
We also added `@JoinColumn` decorator which is required and must be set only on one side of relation.
|
||||
On which side you set `@JoinColumn` that side's table will contain "relation id" and foreign keys to target entity table.
|
||||
Here we added `@OneToOne` to the `profile` and specify the target relation type to be `Profile`.
|
||||
We also added `@JoinColumn` which is required and must be set only on one side of the relation.
|
||||
The side you set `@JoinColumn` on, that side's table will contain a "relation id" and foreign keys to target entity table.
|
||||
|
||||
This example will produce following tables:
|
||||
|
||||
@ -66,9 +66,9 @@ This example will produce following tables:
|
||||
+-------------+--------------+----------------------------+
|
||||
```
|
||||
|
||||
Again, `@JoinColumn` must be set only on one side of relation - which side must have foreign key in the database table.
|
||||
Again, `@JoinColumn` must be set only on one side of relation - the side that must have the foreign key in the database table.
|
||||
|
||||
Example how to save such relation:
|
||||
Example how to save such a relation:
|
||||
|
||||
```typescript
|
||||
const profile = new Profile();
|
||||
@ -100,10 +100,10 @@ const users = await connection
|
||||
.getMany();
|
||||
```
|
||||
|
||||
With eager loading enabled on a relation you don't have to specify relation or join it - it will be loaded automatically ALWAYS.
|
||||
With eager loading enabled on a relation you don't have to specify relation or join it - it will ALWAYS be loaded automatically.
|
||||
|
||||
Relations can be uni-directional and bi-directional.
|
||||
Uni-directional are relations with relation decorator only on one side.
|
||||
Uni-directional are relations with a relation decorator only on one side.
|
||||
Bi-directional are relations with decorators on both sides of a relation.
|
||||
|
||||
We just created a uni-directional relation. Let's make it bi-directional:
|
||||
@ -150,8 +150,8 @@ export class User {
|
||||
}
|
||||
```
|
||||
|
||||
We just made our relation bi-directional. Note, inverse relation does not have a `@JoinColumn` decorator.
|
||||
`@JoinColumn` must be only on one side of the relation - which table will own a foreign key.
|
||||
We just made our relation bi-directional. Note, inverse relation does not have a `@JoinColumn`.
|
||||
`@JoinColumn` must only be on one side of the relation - on the table that will own the foreign key.
|
||||
|
||||
Bi-directional relations allow you to join relations from both sides using `QueryBuilder`:
|
||||
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
# Working with Relations
|
||||
|
||||
`RelationQueryBuilder` is special type of `QueryBuilder` which allows you to work with your relations.
|
||||
Using it you can bind entities to each other in the database without need to load any entity.
|
||||
Using it you can bind entities to each other in the database without need to load any entities.
|
||||
Or you can load related entities easily.
|
||||
Examples:
|
||||
|
||||
For example we have a `Post` entity and it has many-to-many relation to `Category` entity called `categories`.
|
||||
For example we have a `Post` entity and it has a many-to-many relation to `Category` called `categories`.
|
||||
Let's add a new category to this many-to-many relation:
|
||||
|
||||
```typescript
|
||||
@ -18,7 +18,7 @@ await getConnection()
|
||||
.add(category);
|
||||
```
|
||||
|
||||
This code is equivalent of doing this:
|
||||
This code is equivalent to doing this:
|
||||
|
||||
```typescript
|
||||
import {getManager} from "typeorm";
|
||||
@ -29,17 +29,17 @@ post.categories.push(category);
|
||||
await postRepository.save(post);
|
||||
```
|
||||
|
||||
But more efficient because it does minimal number of operations and binds entities in the database,
|
||||
But more efficient because it does a minimal number of operations and binds entities in the database,
|
||||
unlike calling bulky `save` method call.
|
||||
|
||||
Also, benefit of such approach is that you don't need to load everything in entity relation before pushing into it.
|
||||
For example if you would had ten thousands categories inside a single post adding a new post into this list may become problematic for you,
|
||||
because standard way of doing is to load post with all ten thousands categories, push a new category
|
||||
and save it. Result is very heavy performance and basically inapplicable in production results.
|
||||
However, using `RelationQueryBuilder` completely solves this problem.
|
||||
Also, other benefit of such an approach is that you don't need to load every related entity before pushing into it.
|
||||
For example if you have ten thousand categories inside a single post, adding a new post to this list may become problematic for you,
|
||||
because the standard way of doing this, is to load the post with all ten thousand categories, push a new category
|
||||
and save it. This results in very heavy performance and basically inapplicable in production results.
|
||||
However, using `RelationQueryBuilder` solves this problem.
|
||||
|
||||
Also, there is no real need to use entities when you "bind" things, you can use entity ids instead.
|
||||
For example, lets add category with id = 3 into post with id = 1:
|
||||
For example, lets add a category with id = 3 into post with id = 1:
|
||||
|
||||
```typescript
|
||||
import {getConnection} from "typeorm";
|
||||
@ -77,7 +77,7 @@ await getConnection()
|
||||
```
|
||||
|
||||
Adding and removing related entities works in `many-to-many` and `one-to-many` relations.
|
||||
For `one-to-one` and `many-to-one` relations use `set` method instead:
|
||||
For `one-to-one` and `many-to-one` relations use `set` instead:
|
||||
|
||||
```typescript
|
||||
import {getConnection} from "typeorm";
|
||||
@ -103,8 +103,8 @@ await getConnection()
|
||||
.set(null);
|
||||
```
|
||||
|
||||
Besides updating relations relational query builder also allows you to load relational entities.
|
||||
For example, lets say we have inside a `Post` entity many-to-many `categories` relation and many-to-one `user` relation.
|
||||
Besides updating relations, the relational query builder also allows you to load relational entities.
|
||||
For example, lets say inside a `Post` entity we have a many-to-many `categories` relation and a many-to-one `user` relation.
|
||||
To load those relations you can use following code:
|
||||
|
||||
```typescript
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user