SQL and Snowflake Consumers
Writing to SQL Server, Oracle, PostgreSQL, MySQL, and Snowflake — the five queries, and verifying generated SQL before you deploy.
The SQL consumers write Infohub's calculated values into a relational database — the most common way Infohub feeds a corporate warehouse or BI platform. Infohub provides consumers for Microsoft SQL Database, PostgreSQL Database, MySQL Database, and Snowflake.
Connection properties#
Taking Microsoft SQL as representative:
| Property | Notes |
|---|---|
| Server, Database | The destination |
| Username / Password | Blank for Windows integrated security |
| Timeout (seconds) | Statement timeout |
| Maximum Concurrent Connections | Parallel write limit |
| DateTime Precision | How precisely timestamps are written |
| Definition | The stored query definition |
The five queries#
This is what distinguishes a SQL consumer from the others: you control the SQL it writes. Each consumer exposes several statements, one per kind of content:
| Query | Writes |
|---|---|
| Value Query | Measure values |
| Attribute Query | Attribute values |
| Comment Query | Comments |
| Exception Query | Limit exceptions |
| User Query | User-related content |
You only need the ones matching what you are publishing. A consumer feeding a warehouse with numbers needs the Value Query and probably nothing else.
Infohub can generate a starting set of these statements for you, which saves writing them from scratch and gives you the correct shape and parameter names.
Always run the generated SQL manually before deploying. Treat generated SQL as a draft. Take each statement, run it against the destination in a query tool with representative values, and confirm it executes and does what you expect.
Generated statements have to accommodate several database dialects and several content shapes, and the result may need adjusting for your destination's schema, its identity conventions, or its dialect. A statement that fails at run time produces a consumer in the Faulted state and no data at the destination — and that is a much slower way to discover a syntax problem than five minutes in a query tool.
This one habit prevents the most common SQL consumer problem. It also gives you a chance to review what the statement actually does before it starts running unattended against a production warehouse.
Design the destination for restatement#
Infohub's values can change after the fact. A backfill, a corrected calculation, or a late-arriving source value causes the consumer to send that period again.
The Value Query must therefore be idempotent. Sending the same period twice must update, not duplicate.
Approaches, in order of preference:
A merge or upsert. SQL Server's MERGE, PostgreSQL's INSERT ... ON CONFLICT DO UPDATE, MySQL's INSERT ... ON DUPLICATE KEY UPDATE. The destination table needs a unique key over the measure identity and the period.
Delete then insert for the period being written. Simple and correct, more expensive.
Insert with versioning, keeping every version with a load timestamp. Appropriate where the destination is an audit store and needs the history of restatements, and where storage is not a concern.
What does not work is a plain insert into a table with no unique constraint. It appears to work perfectly, and accumulates duplicates that nobody notices until someone sums a column and gets double.
Put the unique constraint on the table. Even with a correct upsert, a unique key over measure identity and period is worth having. It converts a future mistake from silent duplication into a visible error, which is far cheaper to discover.
Measure identity#
The destination needs to know which measure each value belongs to. Consumers let you choose what to send — a measure name, a measure ID, a time scheme name, or a combination.
Measure ID is stable across renames, meaningless to a human reading the warehouse, and not portable between Infohub instances.
Measure name is readable and breaks when someone renames a measure — which is otherwise a safe operation in Infohub.
For a warehouse that people will query directly, names are usually worth the renaming risk, and the mitigation is a naming convention plus a rule that renames are coordinated with the destination's owner.
Whatever you choose, write it down. "Is the key the name or the ID?" is the question nobody can answer a year later, and by then a rename has created what looks like a new series alongside the old one.
Snowflake#
Snowflake behaves like the other SQL consumers with two commercial differences worth planning around.
Compute costs while it runs. A warehouse wakes to service a statement and costs while awake. Many small writes can keep one awake continuously. Prefer fewer, larger sends, and discuss the pattern with whoever owns the Snowflake account before deploying.
Loading patterns differ from transactional databases. Snowflake is optimised for bulk loads rather than row-by-row writes. A consumer sending frequent small batches is working against the grain. Where volume is significant, staging into files that Snowflake loads is more idiomatic — that is a conversation with the destination's team rather than an Infohub setting.
Integrated security#
Leaving username and password blank uses Windows integrated security, which authenticates as the Flow Bootstrap service account once deployed — not as you.
The service account needs write access to the destination, unlike a data source where read is enough. Ask for exactly the rights the statements need: insert and update on the target tables, and nothing more. A consumer account with broad rights on a corporate warehouse is a reasonable thing for a database administrator to object to.
Volume and scheduling#
Do the arithmetic before deploying. Measures × periods × send frequency gives you rows per day, and it is frequently larger than people expect — a thousand measures at hourly intervals is 24,000 rows a day, and a backfill of a year is millions.
Where that matters:
- Keep Maximum Concurrent Connections modest, particularly against a shared warehouse.
- Set a realistic Timeout so a slow statement fails rather than holding a connection.
- Anticipate backfills. If you are about to correct a year of history, tell the destination's owner.
Diagnosing#
| Symptom | Cause |
|---|---|
| Consumer Faulted immediately | SQL error — run the statement manually with real values |
| Nothing arriving, no error | Integration Engine or consumer not deployed |
| Duplicate rows | Value Query inserts rather than upserts; no unique constraint |
| Permission denied when deployed | Bootstrap service account lacks write rights |
| Timestamps off by a fraction | DateTime Precision |
| Sudden large volume | A backfill or recalculation in Infohub |
| A measure appears twice under different names | Renamed in Infohub with name-based identity |
| Snowflake costs higher than expected | Frequent small writes keeping the warehouse awake |
| Values stop for some measures | Namespace filter, or not attached to the consumer |