Describe the issue/error/question
I have an issue that I am trying to build a custom node to query a Presto/Trino database. I am using an external package, and when I try to run a query with this package it works as expected. However, when I put it in an execute
function within a Trino node, it does not.
To give you an idea, here is the package just as a plain js file, which works as expected (apologies but you need a Trino instance to run this, but I am hoping someone can still help me with what the difference is between a pure JS implementation vs an n8n node even without running the code):
import { Trino as TrinoClient } from 'trino-ts'
let updatesNotification = (response) => {
console.log('update', response)
}
let errorNotification = (error) => {
console.log('error', error)
}
let query = 'SELECT * FROM example_table'
const trino = new TrinoClient({
catalog: 'xxx',
schema: 'xxx',
user: '[email protected]',
password: 'xxx',
host: 'xxx',
port: xxx,
source: 'NodeJS Trino Connector',
checkStatusInterval: 1000, //1s
isBasicAuth: true,
isHttps: true,
query: query,
errorNotification,
updatesNotification
})
const res = trino.go()
console.log('res', res)
If I run this, the updatesNotification
function gets called multiple times, as expected, until the query finishes, when I get my result.
I tried to implement this within N8N as a custom node (:
import {
IExecuteFunctions,
} from 'n8n-core'
import {
INodeType,
INodeTypeDescription,
} from 'n8n-workflow'
import { Trino as TrinoClient, TrinoResponse } from 'trino-ts'
export class Trino implements INodeType {
description: INodeTypeDescription = {
displayName: 'Trino / Presto Client',
name: 'trino',
icon: 'file:friendGrid.svg',
group: ['transform'],
version: 1,
description: 'Query data from Trino SQL',
defaults: {
name: 'Trino',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'trino',
required: true,
testedBy: 'trinoCredentialTest'
},
],
properties: [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
options: [
{
name: 'Execute Query',
value: 'executeQuery',
description: 'Execute an SQL query',
action: 'Execute a SQL query',
},
],
default: 'executeQuery',
noDataExpression: true,
},
{
displayName: 'Query',
name: 'query',
type: 'string',
displayOptions: {
show: {
operation: ['executeQuery'],
},
},
default: '',
placeholder: 'SELECT id, name FROM product WHERE id < 40',
required: true,
description: 'The SQL query to execute',
},
],
};
async execute(this: IExecuteFunctions): Promise<any> {
const credentials = await this.getCredentials('trino')
const updatesNotification = (response: TrinoResponse) => {
console.log('update', response)
}
const errorNotification = (error: Error) => {
console.log('error', error)
}
const query = this.getNodeParameter('query', 0) as string;
const trino = new TrinoClient({
catalog: 'awscatalog',
schema: 'bigdata_schema',
user: credentials.user as string,
password: credentials.password as string,
host: credentials.host as string,
port: credentials.port as number,
source: 'NodeJS Trino Connector',
checkStatusInterval: 1000, //1s
isBasicAuth: true,
isHttps: true,
query: query,
errorNotification,
updatesNotification
})
const res = await trino.go();
console.log('res', res) // this will be undefined
}
}
What happens:
- The
updatesNotification
function gets called once, and I see the query in a pending status. - Then the node execution finishes
Instead, what I expect is for the function to be called over and over until finish, just like if I don’t use n8n just nodeJS like the first example. Is there some special way I need to write my execute
function so that it is aware that it has to wait? I’ve tried to check other nodes eg. MySQL but I couldn’t find much difference… it is also await
ing a function and when that executes, it will return the output data.
Any ideas appreciated, thank you in advance!!!
Information on your n8n setup
- n8n version: 0.213.0
- Database you’re using (default: SQLite): SQLite
- Running n8n with the execution process [own(default), main]: own
- Running n8n via [Docker, npm, n8n.cloud, desktop app]: npm