Multi-database/Multi-datasource
Vona ORM supports Multi-database/Multi-datasource, with the following features:
- Multi-database
- For example: PostgreSQL/MySQL
- Support for new database dialects is continuously being added
- Multi-datasource
- Cross-datasource relation queries
The following example uses the User/Order model to query a user's order list to demonstrate how to use Multi-database/Multi-datasource
Preparing Models
First prepare two Models: User/Order
- Model Order
@Model({
entity: EntityOrder,
})
class ModelOrder{}- Model User
@Model({
entity: EntityUser,
relations: {
orders: $relation.hasMany(() => ModelOrder, 'userId'),
},
})
class ModelUser {}Query data
Then query the user's order list
class ServiceOrder {
async selectUserOrders() {
const userId = 1;
const userAndOrders = await this.scope.model.user.get(
{
id: userId,
},
{
include: {
orders: true,
},
},
);
}
}So far, system default datasource has been used to query the user information of userId=1 and the order list of this user
Create Datasources
Next, create two datasources: user-pg and order-mysql
1. Add datasource type definition
In VSCode, create a type file in the module through the context menu
Vona Init/TypesThen add the type definition in the type file
{module path}/src/types/index.ts
declare module 'vona-module-a-orm' {
export interface IDatabaseClientRecord {
'user-pg': never;
'order-mysql': never;
}
}2. Datasources configuration
src/backend/config/config/config.ts
// database
config.database = {
clients: {
'user-pg': {
client: 'pg',
connection: {
host: '127.0.0.1',
port: 5432,
user: 'postgres',
password: '',
database: 'user-xxx',
},
},
'order-mysql': {
client: 'mysql2',
connection: {
host: '127.0.0.1',
port: 3306,
user: 'root',
password: '',
database: 'order-xxx',
},
},
},
};Using Datasources: Dynamic Way
You can use datasources dynamically in your code:
class ServiceOrder {
async selectUserOrders() {
const userId = 1;
+ const modelUser = this.scope.model.user.newInstance('user-pg');
const userAndOrders = await modelUser.get(
{
id: userId,
},
{
include: {
orders: true,
},
},
);
}
}newInstance: Passes the datasource to use and returns a new model instance
So far, we've used the user-pg datasource to query user information and the system default datasource to query order list
Using Datasources: Relation dynamic options
The datasource can be specified dynamically in the relation options:
class ServiceOrder {
async selectUserOrders() {
const userId = 1;
const modelUser = this.scope.model.user.newInstance('user-pg');
const userAndOrders = await modelUser.get(
{
id: userId,
},
{
include: {
orders: {
+ meta: {
+ client: 'order-mysql',
+ },
},
},
},
);
}
}meta.client: specifies the datasource to be used by relationorders
So far, we use the datasource user-pg to query user information and the datasource order-mysql to query order list
Using Datasources: Model options
You can also configure the datasource directly in the Model options to simplify the query code
- Model Order
@Model({
entity: EntityOrder,
+ client: 'order-mysql',
})
class ModelOrder{}- Model User
@Model({
entity: EntityUser,
+ client: 'user-pg',
relations: {
orders: $relation.hasMany(() => ModelOrder, 'userId'),
},
})
class ModelUser {}- Query data
Now, you can query the user's order list in the usual way
class ServiceOrder {
async selectUserOrders() {
const userId = 1;
const userAndOrders = await this.scope.model.user.get(
{
id: userId,
},
{
include: {
orders: true,
},
},
);
}
}Using Datasources: App Config
You can also configure Model options in App Config:
src/backend/config/config/config.ts
// onions
config.onions = {
model: {
'test-vona:user': {
client: 'user-pg',
},
'test-vona:order': {
client: 'order-mysql',
},
},
};Therefore, you can also use the usual way to query the user's order list
Using Datasources: Relation static options
Static options can also be specified when defining a Relation:
@Model({
entity: EntityUser,
client: 'user-pg',
relations: {
orders: $relation.hasMany(() => ModelOrder, 'userId', {
+ meta: {
+ client: 'order-mysql',
+ },
}),
},
})
class ModelUser {}Similarly, you can also use the usual way to query the user's order list