apache/beam · error

failed to prepare query

Error message

failed to prepare query: %v

What it means

After opening the DB, queryFn.ProcessElement prepares the configured SQL statement with db.PrepareContext(ctx, f.Query). Failure is wrapped as "failed to prepare query: %v" with the query text. Prepare asks the server to parse/plan the statement, so this fires on SQL syntax errors, bad placeholders, or nonexistent objects during planning.

Solutions

  1. Copy the query text from the error and run it directly against the database (with placeholders filled) to see the precise SQL error.
  2. Match the placeholder style to the driver ($1... for Postgres, ? for MySQL/sqlite).
  3. Verify all referenced tables/columns exist in the target schema after migrations.
  4. Check the DSN/database name — preparing against the wrong database or schema fails when objects are missing.

Example fix

// before
f.Query = "SELECT * FROM users WHERE id = ?" // Postgres driver

// after
f.Query = "SELECT * FROM users WHERE id = $1"
Defensive patterns

Strategy: validation

Validate before calling

stmt, err := db.PrepareContext(ctx, query)
if err != nil { return fmt.Errorf("prepare failed: %w (check syntax and placeholder style for %s)", err, driver) }

Prevention

When it happens

Trigger: db.PrepareContext returns an error: invalid SQL syntax for the target dialect, wrong parameter placeholder style (? vs $1), referencing a missing table/column at prepare time, or connection dropped before prepare.

Common situations: Queries copied between MySQL and Postgres with incompatible placeholder syntax; typo'd table/column names; schema migrations renaming columns; the connection dying due to idle timeouts before prepare.

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/ec54bfa3f0916d57. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/io/databaseio/database.go:80

	Driver string `json:"driver"`
	// Project is the project
	Dsn string `json:"dsn"`
	// Table is the table identifier.
	Query string `json:"query"`
	// Type is the encoded schema type.
	Type beam.EncodedType `json:"type"`
}

func (f *queryFn) ProcessElement(ctx context.Context, _ []byte, emit func(beam.X)) error {
	//TODO move DB Open and Close to Setup and Teardown methods or StartBundle and FinishBundle
	db, err := sql.Open(f.Driver, f.Dsn)
	if err != nil {
		return errors.Wrapf(err, "failed to open database: %v", f.Driver)
	}
	defer db.Close()
	statement, err := db.PrepareContext(ctx, f.Query)
	if err != nil {
		return errors.Wrapf(err, "failed to prepare query: %v", f.Query)
	}
	defer statement.Close()
	rows, err := statement.QueryContext(ctx)
	if err != nil {
		return errors.Wrapf(err, "failed to run query: %v", f.Query)
	}
	defer rows.Close()
	var mapper rowMapper
	var columns []string
	for rows.Next() {
		reflectRow := reflect.New(f.Type.T)
		row := reflectRow.Interface() // row : *T
		if mapper == nil {
			columns, err = rows.Columns()
			if err != nil {
				return err
			}
			columnsTypes, _ := rows.ColumnTypes()

View on GitHub (pinned to 12126d8942)