mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
✨ Add support for PostgresDB and save date as Date
This commit is contained in:
@@ -68,11 +68,19 @@ n8n start --tunnel
|
||||
```
|
||||
|
||||
|
||||
### Start with MongoDB as Database
|
||||
### Start with other Database
|
||||
|
||||
By default n8n uses SQLite to save credentials, past executions and workflows.
|
||||
To use MongoDB instead you can provide the environment varialbles `DB_TYPE` and
|
||||
`DB_MONGODB_CONNECTION_URL` like in the example bellow.
|
||||
n8n however also supports MongoDB and PostgresDB. To use them simply a few
|
||||
environment variables have to be set.
|
||||
|
||||
|
||||
#### Start with MongoDB as Database
|
||||
|
||||
To use MongoDB as database you can provide the following environment variables like
|
||||
in the example bellow:
|
||||
- `DB_TYPE=mongodb`
|
||||
- `DB_MONGODB_CONNECTION_URL=<CONNECTION_URL>`
|
||||
|
||||
Replace the following placeholders with the actual data:
|
||||
- MONGO_DATABASE
|
||||
@@ -88,6 +96,30 @@ n8n start
|
||||
```
|
||||
|
||||
|
||||
#### Start with PostgresDB as Database
|
||||
|
||||
To use PostgresDB as database you can provide the following environment variables
|
||||
- `DB_TYPE=postgresdb`
|
||||
- `DB_POSTGRESDB_DATABASE` (default: 'n8n')
|
||||
- `DB_POSTGRESDB_HOST` (default: 'localhost')
|
||||
- `DB_POSTGRESDB_PORT` (default: 5432)
|
||||
- `DB_POSTGRESDB_USER` (default: 'root')
|
||||
- `DB_POSTGRESDB_PASSWORD` (default: empty)
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
export DB_TYPE=postgresdb
|
||||
export DB_POSTGRESDB_DATABASE=n8n
|
||||
export DB_POSTGRESDB_HOST=postgresdb
|
||||
export DB_POSTGRESDB_PORT=5432
|
||||
export DB_POSTGRESDB_USER=n8n
|
||||
export DB_POSTGRESDB_PASSWORD=n8n
|
||||
|
||||
n8n start
|
||||
```
|
||||
|
||||
|
||||
## Execute Workflow from CLI
|
||||
|
||||
Workflows can not just be started by triggers, webhooks or manually via the
|
||||
|
||||
@@ -8,7 +8,7 @@ const config = convict({
|
||||
database: {
|
||||
type: {
|
||||
doc: 'Type of database to use',
|
||||
format: ['sqlite', 'mongodb'],
|
||||
format: ['sqlite', 'mongodb', 'postgresdb'],
|
||||
default: 'sqlite',
|
||||
env: 'DB_TYPE'
|
||||
},
|
||||
@@ -20,6 +20,38 @@ const config = convict({
|
||||
env: 'DB_MONGODB_CONNECTION_URL'
|
||||
}
|
||||
},
|
||||
postgresdb: {
|
||||
database: {
|
||||
doc: 'PostgresDB Database',
|
||||
format: String,
|
||||
default: 'n8n',
|
||||
env: 'DB_POSTGRESDB_DATABASE'
|
||||
},
|
||||
host: {
|
||||
doc: 'PostgresDB Host',
|
||||
format: String,
|
||||
default: 'localhost',
|
||||
env: 'DB_POSTGRESDB_HOST'
|
||||
},
|
||||
password: {
|
||||
doc: 'PostgresDB Password',
|
||||
format: String,
|
||||
default: '',
|
||||
env: 'DB_POSTGRESDB_PASSWORD'
|
||||
},
|
||||
port: {
|
||||
doc: 'PostgresDB Port',
|
||||
format: Number,
|
||||
default: 5432,
|
||||
env: 'DB_POSTGRESDB_PORT'
|
||||
},
|
||||
user: {
|
||||
doc: 'PostgresDB User',
|
||||
format: String,
|
||||
default: 'root',
|
||||
env: 'DB_POSTGRESDB_USER'
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
executions: {
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
"n8n-nodes-base": "^0.7.0",
|
||||
"n8n-workflow": "^0.6.0",
|
||||
"open": "^6.1.0",
|
||||
"pg": "^7.11.0",
|
||||
"request-promise-native": "^1.0.7",
|
||||
"sqlite3": "^4.0.6",
|
||||
"sse-channel": "^3.1.1",
|
||||
|
||||
@@ -18,6 +18,7 @@ import * as config from './../config';
|
||||
|
||||
import {
|
||||
MongoDb,
|
||||
PostgresDb,
|
||||
SQLite,
|
||||
} from './databases';
|
||||
|
||||
@@ -43,6 +44,16 @@ export async function init(): Promise<IDatabaseCollections> {
|
||||
url: config.get('database.mongodb.connectionUrl') as string,
|
||||
useNewUrlParser: true,
|
||||
};
|
||||
} else if (dbType === 'postgresdb') {
|
||||
entities = PostgresDb;
|
||||
connectionOptions = {
|
||||
type: 'postgres',
|
||||
database: config.get('database.postgresdb.database'),
|
||||
host: config.get('database.postgresdb.host'),
|
||||
password: config.get('database.postgresdb.password'),
|
||||
port: config.get('database.postgresdb.port'),
|
||||
username: config.get('database.postgresdb.user'),
|
||||
};
|
||||
} else if (dbType === 'sqlite') {
|
||||
entities = SQLite;
|
||||
connectionOptions = {
|
||||
|
||||
@@ -41,8 +41,8 @@ export interface IWorkflowBase {
|
||||
id?: number | string | ObjectID;
|
||||
name: string;
|
||||
active: boolean;
|
||||
createdAt: number | string;
|
||||
updatedAt: number | string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
nodes: INode[];
|
||||
connections: IConnections;
|
||||
settings?: IWorkflowSettings;
|
||||
@@ -63,13 +63,13 @@ export interface IWorkflowShortResponse {
|
||||
id: string;
|
||||
name: string;
|
||||
active: boolean;
|
||||
createdAt: number | string;
|
||||
updatedAt: number | string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface ICredentialsBase {
|
||||
createdAt: number | string;
|
||||
updatedAt: number | string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface ICredentialsDb extends ICredentialsBase, ICredentialsEncrypted{
|
||||
@@ -88,14 +88,14 @@ export interface ICredentialsDecryptedResponse extends ICredentialsDecryptedDb {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export type DatabaseType = 'mongodb' | 'sqlite';
|
||||
export type DatabaseType = 'mongodb' | 'postgresdb' | 'sqlite';
|
||||
export type SaveExecutionDataType = 'all' | 'none';
|
||||
|
||||
export interface IExecutionBase {
|
||||
id?: number | string | ObjectID;
|
||||
mode: WorkflowExecuteMode;
|
||||
startedAt: number;
|
||||
stoppedAt: number;
|
||||
startedAt: Date;
|
||||
stoppedAt: Date;
|
||||
workflowId?: string; // To be able to filter executions easily //
|
||||
finished: boolean;
|
||||
retryOf?: number | string | ObjectID; // If it is a retry, the id of the execution it is a retry of.
|
||||
@@ -148,8 +148,8 @@ export interface IExecutionsListResponse {
|
||||
export interface IExecutionsStopData {
|
||||
finished?: boolean;
|
||||
mode: WorkflowExecuteMode;
|
||||
startedAt: number | string;
|
||||
stoppedAt: number | string;
|
||||
startedAt: Date;
|
||||
stoppedAt: Date;
|
||||
}
|
||||
|
||||
export interface IExecutionsSummary {
|
||||
@@ -158,14 +158,14 @@ export interface IExecutionsSummary {
|
||||
finished?: boolean;
|
||||
retryOf?: string;
|
||||
retrySuccessId?: string;
|
||||
startedAt: number | string;
|
||||
stoppedAt?: number | string;
|
||||
startedAt: Date;
|
||||
stoppedAt?: Date;
|
||||
workflowId: string;
|
||||
workflowName?: string;
|
||||
}
|
||||
|
||||
export interface IExecutionDeleteFilter {
|
||||
deleteBefore?: number;
|
||||
deleteBefore?: Date;
|
||||
filters?: IDataObject;
|
||||
ids?: string[];
|
||||
}
|
||||
@@ -186,6 +186,12 @@ export interface IN8nConfigDatabase {
|
||||
mongodb: {
|
||||
connectionUrl: string;
|
||||
};
|
||||
postgresdb: {
|
||||
host: string;
|
||||
password: string;
|
||||
port: number;
|
||||
user: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IN8nConfigEndpoints {
|
||||
|
||||
@@ -105,8 +105,8 @@ class App {
|
||||
* @returns {number}
|
||||
* @memberof App
|
||||
*/
|
||||
getCurrentDate(): number {
|
||||
return Math.floor(new Date().getTime());
|
||||
getCurrentDate(): Date {
|
||||
return new Date();
|
||||
}
|
||||
|
||||
|
||||
@@ -851,7 +851,7 @@ class App {
|
||||
id: data.id.toString(),
|
||||
workflowId: data.workflowId,
|
||||
mode:data.mode,
|
||||
startedAt: data.startedAt,
|
||||
startedAt: new Date(data.startedAt),
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -873,8 +873,8 @@ class App {
|
||||
|
||||
const returnData: IExecutionsStopData = {
|
||||
mode: result.mode,
|
||||
startedAt: result.startedAt,
|
||||
stoppedAt: result.stoppedAt,
|
||||
startedAt: new Date(result.startedAt),
|
||||
stoppedAt: new Date(result.stoppedAt),
|
||||
finished: result.finished,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import * as MongoDb from './mongodb';
|
||||
import * as PostgresDb from './postgresdb';
|
||||
import * as SQLite from './sqlite';
|
||||
|
||||
export {
|
||||
MongoDb,
|
||||
PostgresDb,
|
||||
SQLite,
|
||||
};
|
||||
|
||||
@@ -33,9 +33,9 @@ export class CredentialsEntity implements ICredentialsDb {
|
||||
@Column('json')
|
||||
nodesAccess: ICredentialNodeAccess[];
|
||||
|
||||
@Column()
|
||||
createdAt: number;
|
||||
@Column('Date')
|
||||
createdAt: Date;
|
||||
|
||||
@Column()
|
||||
updatedAt: number;
|
||||
@Column('Date')
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
@@ -36,11 +36,11 @@ export class ExecutionEntity implements IExecutionFlattedDb {
|
||||
@Column()
|
||||
retrySuccessId: string;
|
||||
|
||||
@Column()
|
||||
startedAt: number;
|
||||
@Column('Date')
|
||||
startedAt: Date;
|
||||
|
||||
@Column()
|
||||
stoppedAt: number;
|
||||
@Column('Date')
|
||||
stoppedAt: Date;
|
||||
|
||||
@Column('json')
|
||||
workflowData: IWorkflowDb;
|
||||
|
||||
@@ -34,11 +34,11 @@ export class WorkflowEntity implements IWorkflowDb {
|
||||
@Column('json')
|
||||
connections: IConnections;
|
||||
|
||||
@Column()
|
||||
createdAt: number;
|
||||
@Column('Date')
|
||||
createdAt: Date;
|
||||
|
||||
@Column()
|
||||
updatedAt: number;
|
||||
@Column('Date')
|
||||
updatedAt: Date;
|
||||
|
||||
@Column('json')
|
||||
settings?: IWorkflowSettings;
|
||||
|
||||
44
packages/cli/src/databases/postgresdb/CredentialsEntity.ts
Normal file
44
packages/cli/src/databases/postgresdb/CredentialsEntity.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import {
|
||||
ICredentialNodeAccess,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
ICredentialsDb,
|
||||
} from '../../';
|
||||
|
||||
import {
|
||||
Column,
|
||||
Entity,
|
||||
Index,
|
||||
PrimaryGeneratedColumn,
|
||||
} from "typeorm";
|
||||
|
||||
@Entity()
|
||||
export class CredentialsEntity implements ICredentialsDb {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column({
|
||||
length: 128
|
||||
})
|
||||
name: string;
|
||||
|
||||
@Column('text')
|
||||
data: string;
|
||||
|
||||
@Index()
|
||||
@Column({
|
||||
length: 32
|
||||
})
|
||||
type: string;
|
||||
|
||||
@Column('json')
|
||||
nodesAccess: ICredentialNodeAccess[];
|
||||
|
||||
@Column('timestamp')
|
||||
createdAt: Date;
|
||||
|
||||
@Column('timestamp')
|
||||
updatedAt: Date;
|
||||
}
|
||||
51
packages/cli/src/databases/postgresdb/ExecutionEntity.ts
Normal file
51
packages/cli/src/databases/postgresdb/ExecutionEntity.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import {
|
||||
WorkflowExecuteMode,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
IExecutionFlattedDb,
|
||||
IWorkflowDb,
|
||||
} from '../../';
|
||||
|
||||
import {
|
||||
Column,
|
||||
Entity,
|
||||
Index,
|
||||
PrimaryGeneratedColumn,
|
||||
} from "typeorm";
|
||||
|
||||
|
||||
@Entity()
|
||||
export class ExecutionEntity implements IExecutionFlattedDb {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column('text')
|
||||
data: string;
|
||||
|
||||
@Column()
|
||||
finished: boolean;
|
||||
|
||||
@Column()
|
||||
mode: WorkflowExecuteMode;
|
||||
|
||||
@Column({ nullable: true })
|
||||
retryOf: string;
|
||||
|
||||
@Column({ nullable: true })
|
||||
retrySuccessId: string;
|
||||
|
||||
@Column('timestamp')
|
||||
startedAt: Date;
|
||||
|
||||
@Column('timestamp')
|
||||
stoppedAt: Date;
|
||||
|
||||
@Column('json')
|
||||
workflowData: IWorkflowDb;
|
||||
|
||||
@Index()
|
||||
@Column({ nullable: true })
|
||||
workflowId: string;
|
||||
}
|
||||
55
packages/cli/src/databases/postgresdb/WorkflowEntity.ts
Normal file
55
packages/cli/src/databases/postgresdb/WorkflowEntity.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import {
|
||||
IConnections,
|
||||
IDataObject,
|
||||
INode,
|
||||
IWorkflowSettings,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
IWorkflowDb,
|
||||
} from '../../';
|
||||
|
||||
import {
|
||||
Column,
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
} from "typeorm";
|
||||
|
||||
@Entity()
|
||||
export class WorkflowEntity implements IWorkflowDb {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column({
|
||||
length: 128
|
||||
})
|
||||
name: string;
|
||||
|
||||
@Column()
|
||||
active: boolean;
|
||||
|
||||
@Column('json')
|
||||
nodes: INode[];
|
||||
|
||||
@Column('json')
|
||||
connections: IConnections;
|
||||
|
||||
@Column('timestamp')
|
||||
createdAt: Date;
|
||||
|
||||
@Column('timestamp')
|
||||
updatedAt: Date;
|
||||
|
||||
@Column({
|
||||
type: 'json',
|
||||
nullable: true,
|
||||
})
|
||||
settings?: IWorkflowSettings;
|
||||
|
||||
@Column({
|
||||
type: 'json',
|
||||
nullable: true,
|
||||
})
|
||||
staticData?: IDataObject;
|
||||
}
|
||||
3
packages/cli/src/databases/postgresdb/index.ts
Normal file
3
packages/cli/src/databases/postgresdb/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './CredentialsEntity';
|
||||
export * from './ExecutionEntity';
|
||||
export * from './WorkflowEntity';
|
||||
@@ -37,8 +37,8 @@ export class CredentialsEntity implements ICredentialsDb {
|
||||
nodesAccess: ICredentialNodeAccess[];
|
||||
|
||||
@Column()
|
||||
createdAt: number;
|
||||
createdAt: Date;
|
||||
|
||||
@Column()
|
||||
updatedAt: number;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
@@ -39,10 +39,10 @@ export class ExecutionEntity implements IExecutionFlattedDb {
|
||||
retrySuccessId: string;
|
||||
|
||||
@Column()
|
||||
startedAt: number;
|
||||
startedAt: Date;
|
||||
|
||||
@Column()
|
||||
stoppedAt: number;
|
||||
stoppedAt: Date;
|
||||
|
||||
@Column('simple-json')
|
||||
workflowData: IWorkflowDb;
|
||||
|
||||
@@ -36,10 +36,10 @@ export class WorkflowEntity implements IWorkflowDb {
|
||||
connections: IConnections;
|
||||
|
||||
@Column()
|
||||
createdAt: number;
|
||||
createdAt: Date;
|
||||
|
||||
@Column()
|
||||
updatedAt: number;
|
||||
updatedAt: Date;
|
||||
|
||||
@Column({
|
||||
type: 'simple-json',
|
||||
|
||||
Reference in New Issue
Block a user