micro/go-micro · error

model/postgres: create table: %w

Error message

model/postgres: create table: %w

What it means

Register ensures the schema's table exists by running CREATE TABLE IF NOT EXISTS with columns derived from schema.Fields. If the database rejects that DDL statement, the error is wrapped as "model/postgres: create table" preserving the underlying pq/pgx error.

Source

Thrown at model/postgres/postgres.go:64

	d.mu.Lock()
	d.schemas[schema.Table] = schema
	d.types[t] = schema
	d.mu.Unlock()

	var cols []string
	for _, f := range schema.Fields {
		colType := goTypeToPostgres(f.Type)
		col := fmt.Sprintf("%s %s", quoteIdent(f.Column), colType)
		if f.IsKey {
			col += " PRIMARY KEY"
		}
		cols = append(cols, col)
	}

	query := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s (%s)", quoteIdent(schema.Table), strings.Join(cols, ", "))
	if _, err := d.db.Exec(query); err != nil {
		return fmt.Errorf("model/postgres: create table: %w", err)
	}

	for _, f := range schema.Fields {
		if f.Index && !f.IsKey {
			idx := fmt.Sprintf("CREATE INDEX IF NOT EXISTS %s ON %s (%s)",
				quoteIdent("idx_"+schema.Table+"_"+f.Column),
				quoteIdent(schema.Table),
				quoteIdent(f.Column))
			if _, err := d.db.Exec(idx); err != nil {
				return fmt.Errorf("model/postgres: create index: %w", err)
			}
		}
	}

	return nil
}

func (d *postgresModel) schema(v interface{}) (*model.Schema, error) {

View on GitHub (pinned to 24529f1404)

Solutions

  1. Read the wrapped cause (%w) for the real Postgres error — it names the exact problem (permission, syntax, connection).
  2. Grant the connecting role CREATE privilege on the schema, or run DDL with a migration user.
  3. Fix table/column identifiers in the model schema; quote reserved words (the driver's quoteIdent usually handles this).
  4. Verify connectivity (DSN, network, DB up) with psql before starting the app.
  5. Prefer an external migration tool and make Register tolerant if the table is managed elsewhere.

Example fix

// before
db, _ := NewPostgresModel(dburl) // auto Register fails on readonly role

// after
-- grant once as superuser
GRANT CREATE ON SCHEMA public TO app_user;
// then
if err := store.Register(ctx, &User{}); err != nil {
    log.Fatalf("schema setup failed: %v", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before Register: check privileges and connectivity
var hasCreate bool
if err := db.QueryRow(
    "SELECT has_schema_privilege(current_user, 'public', 'CREATE')",
).Scan(&hasCreate); err != nil {
    return err
}
if !hasCreate {
    return errors.New("db role lacks CREATE privilege on schema public")
}

Try / catch

if err := store.Register(ctx, &User{}); err != nil {
    var pgErr *pgconn.PgError
    if errors.As(err, &pgErr) {
        log.Printf("create table failed [%s]: %s", pgErr.Code, pgErr.Message)
    }
    return fmt.Errorf("schema bootstrap: %w", err)
}

Prevention

When it happens

Trigger: Calling postgresModel.Register (or New/postgres model setup that auto-registers) when the CREATE TABLE fails: invalid table/column names, reserved SQL keywords used unquoted, insufficient privileges, or the database being unreachable.

Common situations: App user lacking CREATE privilege on the schema, table name colliding with reserved words, read-only replicas or restricted production credentials, or connecting to a database where another system owns the migration.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/7c488311e3f4f585. Report an issue: GitHub.