node-red-contrib-postgresql
Version:
Node-RED node for PostgreSQL, supporting parameters, split, back-pressure
129 lines (113 loc) • 5.73 kB
HTML
<script type="text/x-red" data-help-name="postgresql">
<p>
<a href="https://github.com/alexandrainst/node-red-contrib-postgresql">node-red-contrib-postgresql</a>
is a Node-RED node to query a <a href="https://www.postgresql.org/">PostgreSQL</a> 🐘 database.
</p>
<h3>Outputs</h3>
<p>The response (rows) is provided in <code>msg.payload</code> as an array.</p>
<p>
An exception is if the <em>Split results</em> option is enabled and the <em>Number of rows per message</em> is set to 1,
then <code>msg.payload</code> is not an array but the single-row response.
</p>
<p>
Additional information is provided as <code>msg.pgsql.rowCount</code> and <code>msg.pgsql.command</code>.
See the <a href="https://node-postgres.com/apis/result">underlying documentation</a> for details.
</p>
<p>In the case of multiple queries, then <code>msg.pgsql</code> is an array.</p>
<h3>Inputs</h3>
<h4>SQL query template</h4>
<p>This node uses the <a href="https://github.com/janl/mustache.js">Mustache template system</a> to generate queries based on the message:</p>
<pre>
-- INTEGER id column
SELECT * FROM table WHERE id = {{{ msg.id }}}
-- TEXT id column
SELECT * FROM table WHERE id = '{{{ msg.id }}}'
</pre>
<h4>Dynamic SQL queries</h4>
<p>As an alternative to using the query template above, this node also accepts an SQL query via the <code>msg.query</code> parameter.</p>
<h4>Parameterized queries</h4>
<p>Parameters for parameterized queries can be passed as an array <code>msg.params</code>:</p>
<pre>
// In a function, provide parameters for the parameterized query
msg.params = [ msg.id ];
</pre>
<pre>
-- In this node, use a parameterized query
SELECT * FROM table WHERE id = $1
</pre>
<h4>Parameterized queries</h4>
<p>
As an alternative to numeric parameters,
named parameters for parameterized queries can be passed as a parameter object <code>msg.queryParameters</code>:
</p>
<pre>
// In a function, provide parameters for the named parameterized query
msg.queryParameters.id = msg.id;
</pre>
<pre>
-- In this node, use a named parameterized query
SELECT * FROM table WHERE id = $id;
</pre>
<p>
<em>Note</em>: named parameters are not natively supported by PostgreSQL, and this library just emulates them,
so this is less robust than numeric parameters.
</p>
<h4>Dynamic PostgreSQL connection parameters</h4>
<p>
If the information about which database server to connect and how needs to be dynamic,
it is possible to pass a <a href="https://node-postgres.com/apis/client">custom client configuration</a> in the message:
</p>
<pre>
msg.pgConfig = {
user?: string, // default process.env.PGUSER || process.env.USER
password?: string, //or function, default process.env.PGPASSWORD
host?: string, // default process.env.PGHOST
database?: string, // default process.env.PGDATABASE || process.env.USER
port?: number, // default process.env.PGPORT
connectionString?: string, // e.g. postgres://user:password@host:5432/database
ssl?: any, // passed directly to node.TLSSocket, supports all tls.connect options
types?: any, // custom type parsers
statement_timeout?: number, // number of milliseconds before a statement in query will time out, default is no timeout
query_timeout?: number, // number of milliseconds before a query call will timeout, default is no timeout
application_name?: string, // The name of the application that created this Client instance
connectionTimeoutMillis?: number, // number of milliseconds to wait for connection, default is no timeout
idle_in_transaction_session_timeout?: number, // number of milliseconds before terminating any session with an open idle transaction, default is no timeout
};
</pre>
<p>
However, this does not use a <a href="https://node-postgres.com/features/pooling">connection pool</a>, and is therefore less efficient.
It is therefore recommended in most cases not to use <code>msg.pgConfig</code> at all and instead stick to the built-in configuration node.
</p>
<h3>Backpressure</h3>
<p>
This node supports <em>backpressure</em> / <em>flow control</em>:
when the <em>Split results</em> option is enabled, it waits for a <em>tick</em> before releasing the next batch of lines,
to make sure the rest of your Node-RED flow is ready to process more data
(instead of risking an out-of-memory condition), and also conveys this information upstream.
</p><p>
So when the <em>Split results</em> option is enabled, this node will only output one message at first,
and then awaits a message containing a truthy <code>msg.tick</code> before releasing the next message.
</p><p>
To make this behaviour potentially automatic (avoiding manual wires),
this node declares its ability by exposing a truthy <code>node.tickConsumer</code> for downstream nodes to detect this feature,
and a truthy <code>node.tickProvider</code> for upstream nodes.
Likewise, this node detects upstream nodes using the same back-pressure convention, and automatically sends ticks.
</p>
<h3>Sequences for split results</h3>
<p>
When the <em>Split results</em> option is enabled (streaming), the messages contain some information following the conventions
for <a href="https://nodered.org/docs/user-guide/messages#message-sequences"><em>messages sequences</em></a>.
</p>
<pre>
{
payload: '...',
parts: {
id: 0.1234, // sequence ID, randomly generated (changes for every sequence)
index: 5, // incremented for each message of the same sequence
count: 6, // total number of messages; only available in the last message of a sequence
parts: {}, // optional upstream parts information
},
complete: true, // True only for the last message of a sequence
}
</pre>
</script>