superapp
BackendDatabases

MySQL

Connect to MySQL databases.

Attach a MySQL database and get full CRUD through DuckDB's native mysql_scanner extension.

import { createEngine } from '@superapp/backend'
import { mysqlProvider } from '@superapp/backend/integrations/mysql'

const engine = createEngine({
  integrations: [mysqlProvider],
  connections: {
    warehouse: { type: 'mysql', url: process.env.MYSQL_URL! },
  },
})

Connection URL Format

Standard MySQL connection string:

mysql://user:password@host:3306/database
ParameterDescription
userDatabase user
passwordDatabase password
hostServer hostname or IP
3306Port (default: 3306)
databaseDatabase name

What DuckDB Generates

When the engine starts, the MySQL provider generates:

INSTALL mysql;
LOAD mysql;
ATTACH 'host=host user=user password=password port=3306 database=database' AS warehouse (TYPE MYSQL, READ_WRITE);

All tables in the target database become available under the warehouse schema. DuckDB pushes filters and aggregations down to MySQL whenever possible.

Capabilities

OperationSupported
findMany / findOneYes
createYes
updateYes
deleteYes
count / aggregateYes
TransactionsYes

Full Example

import { createEngine } from '@superapp/backend'
import { mysqlProvider } from '@superapp/backend/integrations/mysql'
import { createHonoMiddleware } from '@superapp/backend/adapters/hono'
import { Hono } from 'hono'
import { serve } from '@hono/node-server'

const engine = createEngine({
  integrations: [mysqlProvider],
  connections: {
    warehouse: { type: 'mysql', url: process.env.MYSQL_URL! },
  },
  permissions: {
    read_customers: {
      name: 'Read customers',
      table: 'warehouse.customers',
      operations: { select: true },
      columns: ['id', 'name', 'email', 'created_at'],
    },
  },
  roles: {
    viewer: ['read_customers'],
  },
})

const app = new Hono()
app.route('/', createHonoMiddleware(engine))
serve({ fetch: app.fetch, port: 3001 })

Combining with Other Providers

MySQL works alongside any other provider. A common pattern is Postgres for your primary database and MySQL for a legacy warehouse:

import { postgresProvider } from '@superapp/backend/integrations/postgres'
import { mysqlProvider } from '@superapp/backend/integrations/mysql'

const engine = createEngine({
  integrations: [postgresProvider, mysqlProvider],
  connections: {
    main: { type: 'postgres', url: process.env.PG_URL! },
    warehouse: { type: 'mysql', url: process.env.MYSQL_URL! },
  },
})

Tables are namespaced: main.orders, warehouse.customers.

Troubleshooting

ProblemCauseFix
Connection refusedMySQL not reachableCheck host, port, and firewall rules
Access deniedWrong credentialsVerify user/password in connection URL
Unknown databaseDatabase does not existCheck database name in the URL
Too many connectionsPool exhausted on MySQL sideIncrease max_connections in MySQL config
SSL requiredServer enforces SSLAdd ?ssl-mode=REQUIRED to the URL

On this page