Skip to main content

MySQL

The mysql reader runs read-only SELECT queries on MySQL and MariaDB databases. It leverages DuckDB's native MySQL extension to attach the database in read-only mode, and validates every query through AST inspection before execution to prevent mutations or multi-statement injection.

Use either connection keys or a single DSN secret.

Connection keys​

Use when connection parameters are environment configurations and the password is kept in secrets:

source.yaml
spec:
config:
mysql_host: { type: string, default: localhost }
mysql_port: { type: integer, default: 3306 }
mysql_database: { type: string, default: app_db }
secrets:
mysql_password: { type: string }
auth:
provider: mysql
host: "{{ config.mysql_host }}"
port: "{{ config.mysql_port }}"
database: "{{ config.mysql_database }}"
user: reader
password: "{{ secrets.mysql_password }}"
statement_timeout: 5min

DSN secret​

Use when the connection string is provided as a complete URI:

source.yaml
auth:
provider: mysql
dsn: "{{ secrets.mysql_dsn }}"

Format: mysql://user:password@host:port/database.

Queries​

streams/users.yaml
requests:
- name: raw_users
sdk: mysql
service: database
method: query
arguments:
query: |
SELECT id, username, email, created_at
FROM users
WHERE created_at >= $since
params: { since: "{{ window.start }}" }

transform:
mode: page
steps:
- name: users
select: |
SELECT
(record->>'id')::BIGINT AS user_id,
record->>'username' AS username,
record->>'email' AS email,
(record->>'created_at')::TIMESTAMPTZ AS created_at
FROM raw_users

export:
users:
step: users
primary_key: [user_id]

Queries are read-only (single SELECT per request) and parameterized with $name bindings to prevent SQL injection.