Generic Database Connector
The Generic Database connector works with any ADO.NET-compatible database, including SQL Server, PostgreSQL, MySQL, SQLite, Oracle, and more.
Overview
- Source: Query databases using bulk, incrementing, or timestamp modes
- Sink: Insert, upsert, or update records in database tables
Use Cases:
- Database-to-database synchronization
- Batch data extraction
- Event logging to SQL databases
- Legacy system integration
Quick Start
Database Source
Query data from a database:
{
"name": "db-source",
"config": {
"connector.class": "DatabaseSourceConnector",
"database.provider": "Npgsql",
"database.connection.string": "Host=localhost;Database=mydb;Username=user;Password=pass",
"database.table": "events",
"topic": "db-events",
"mode": "incrementing",
"incrementing.column": "id"
}
}
Database Sink
Write data to a database:
{
"name": "db-sink",
"config": {
"connector.class": "DatabaseSinkConnector",
"database.provider": "Npgsql",
"database.connection.string": "Host=localhost;Database=mydb;Username=user;Password=pass",
"topics": "user-events",
"database.table": "event_log",
"write.mode": "insert"
}
}
Configuration Reference
Connection Settings
| Option | Type | Default | Description |
|---|---|---|---|
database.provider |
string | Required | ADO.NET provider name |
database.connection.string |
string | Required | Connection string |
database.table |
string | - | Table name (supports ${topic} pattern) |
Source Settings
| Option | Type | Default | Description |
|---|---|---|---|
topic |
string | Required | Destination Surgewave topic |
mode |
string | bulk |
Mode: bulk, incrementing, timestamp, timestamp+incrementing |
incrementing.column |
string | - | Auto-incrementing column |
timestamp.column |
string | - | Timestamp column |
query |
string | - | Custom SQL query |
poll.interval.ms |
long | 10000 |
Polling interval |
batch.size |
int | 1000 |
Rows per batch |
Sink Settings
| Option | Type | Default | Description |
|---|---|---|---|
topics |
string | Required | Source Surgewave topics |
write.mode |
string | insert |
Mode: insert, upsert, update |
pk.fields |
string | - | Primary key fields for upsert/update |
batch.size |
int | 1000 |
Records per batch |
Supported Providers
Provider Names
| Database | Provider Name | NuGet Package |
|---|---|---|
| PostgreSQL | Npgsql |
Npgsql |
| SQL Server | Microsoft.Data.SqlClient |
Microsoft.Data.SqlClient |
| MySQL | MySql.Data.MySqlClient |
MySql.Data |
| SQLite | Microsoft.Data.Sqlite |
Microsoft.Data.Sqlite |
| Oracle | Oracle.ManagedDataAccess.Client |
Oracle.ManagedDataAccess.Core |
Connection String Examples
PostgreSQL:
Host=localhost;Port=5432;Database=mydb;Username=user;Password=pass
SQL Server:
Server=localhost;Database=mydb;User Id=user;Password=pass;TrustServerCertificate=True
MySQL:
Server=localhost;Port=3306;Database=mydb;Uid=user;Pwd=pass
SQLite:
Data Source=/path/to/database.db
Source Modes
Bulk Mode
Reads entire table on each poll (for small tables or full syncs):
{
"mode": "bulk",
"poll.interval.ms": "60000"
}
Incrementing Mode
Tracks progress using an auto-incrementing column:
{
"mode": "incrementing",
"incrementing.column": "id"
}
Only reads rows where id > last_seen_id.
Timestamp Mode
Tracks progress using a timestamp column:
{
"mode": "timestamp",
"timestamp.column": "updated_at"
}
Only reads rows where updated_at > last_seen_timestamp.
Timestamp + Incrementing
Combines both for reliable change detection:
{
"mode": "timestamp+incrementing",
"timestamp.column": "updated_at",
"incrementing.column": "id"
}
Custom Queries
Use custom SQL for complex extractions:
{
"query": "SELECT id, name, email, updated_at FROM users WHERE status = 'active' AND updated_at > :timestamp ORDER BY updated_at, id",
"mode": "timestamp+incrementing",
"timestamp.column": "updated_at",
"incrementing.column": "id"
}
Parameters:
:timestamp- Last seen timestamp:incrementing- Last seen incrementing value
Sink Write Modes
Insert
Insert new rows (fails on duplicates):
{
"write.mode": "insert"
}
Upsert
Insert or update based on primary key:
{
"write.mode": "upsert",
"pk.fields": "id"
}
Generates database-specific upsert syntax:
- PostgreSQL:
INSERT ... ON CONFLICT DO UPDATE - SQL Server:
MERGE - MySQL:
INSERT ... ON DUPLICATE KEY UPDATE
Update
Update existing rows only:
{
"write.mode": "update",
"pk.fields": "id"
}
Table Name Patterns
Use ${topic} to dynamically set table name:
{
"database.table": "${topic}_events"
}
Topic user-actions writes to table user-actions_events.
Examples
SQL Server to PostgreSQL
Replicate data between databases:
Source (SQL Server):
{
"name": "sqlserver-source",
"config": {
"connector.class": "DatabaseSourceConnector",
"database.provider": "Microsoft.Data.SqlClient",
"database.connection.string": "Server=sql.example.com;Database=source;User Id=reader;Password=pass",
"database.table": "orders",
"topic": "orders-sync",
"mode": "timestamp+incrementing",
"timestamp.column": "modified_at",
"incrementing.column": "order_id"
}
}
Sink (PostgreSQL):
{
"name": "postgres-sink",
"config": {
"connector.class": "DatabaseSinkConnector",
"database.provider": "Npgsql",
"database.connection.string": "Host=pg.example.com;Database=dest;Username=writer;Password=pass",
"topics": "orders-sync",
"database.table": "orders",
"write.mode": "upsert",
"pk.fields": "order_id"
}
}
Event Logging
Log Surgewave events to a database:
{
"name": "event-logger",
"config": {
"connector.class": "DatabaseSinkConnector",
"database.provider": "Npgsql",
"database.connection.string": "Host=localhost;Database=logs;Username=logger;Password=pass",
"topics": "application-events,system-events",
"database.table": "${topic}",
"write.mode": "insert",
"batch.size": "500"
}
}
SQLite for Testing
Local development with SQLite:
{
"name": "sqlite-sink",
"config": {
"connector.class": "DatabaseSinkConnector",
"database.provider": "Microsoft.Data.Sqlite",
"database.connection.string": "Data Source=test.db",
"topics": "test-events",
"database.table": "events",
"write.mode": "insert"
}
}
Schema Requirements
Source Tables
Tables should have:
- Primary key or unique incrementing column
- Timestamp column for change tracking (recommended)
- Index on tracking columns for performance
Sink Tables
Create tables before starting sink connector:
CREATE TABLE events (
id SERIAL PRIMARY KEY,
topic VARCHAR(255),
key BYTEA,
value JSONB,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Troubleshooting
Common Issues
Connection Refused
- Verify database server is running
- Check firewall rules
- Ensure connection string is correct
Permission Denied
- Verify user has SELECT permission (source)
- Verify user has INSERT/UPDATE permission (sink)
- Check table ownership
Slow Performance
- Add indexes on tracking columns
- Increase
batch.size - Reduce
poll.interval.ms
Provider Registration
If provider not found, register it in code:
DbProviderFactories.RegisterFactory("Npgsql", Npgsql.NpgsqlFactory.Instance);
DbProviderFactories.RegisterFactory("MySql.Data.MySqlClient", MySql.Data.MySqlClient.MySqlClientFactory.Instance);