pathwaycom/pathway · error · ValueError

pw.io.mysql.read requires at least one primary key column in

Error message

pw.io.mysql.read requires at least one primary key column in the schema. Mark the column(s) that form the table's primary key with pw.column_definition(primary_key=True).

What it means

Pathway's MySQL connector tracks row changes by mapping each source row to a Pathway table key, which requires the schema to declare at least one primary-key column. This ValueError is raised at pw.io.mysql.read() call time when schema.primary_key_columns() is empty, telling you to mark the key column(s) with pw.column_definition(primary_key=True).

Source

Thrown at python/pathway/io/mysql/__init__.py:191

    >>> persistence_config = pw.persistence.Config(  # doctest: +SKIP
    ...     backend=pw.persistence.Backend.filesystem("./PStorage")
    ... )
    >>> table = pw.io.mysql.read(  # doctest: +SKIP
    ...     "mysql://testuser:testpass@localhost:3306/testdb",
    ...     table_name="my_table",
    ...     schema=MySchema,
    ...     name="my_mysql_source",
    ... )
    >>> pw.io.jsonlines.write(table, "output.jsonl")  # doctest: +SKIP
    >>> pw.run(persistence_config=persistence_config)  # doctest: +SKIP
    """
    _check_entitlements("mysql")

    schema, api_schema = read_schema(schema)

    primary_key_columns = schema.primary_key_columns()
    if not primary_key_columns:
        raise ValueError(
            "pw.io.mysql.read requires at least one primary key column in the schema. "
            "Mark the column(s) that form the table's primary key with "
            "pw.column_definition(primary_key=True)."
        )

    pk_dtypes = schema._dtypes()
    nullable_pks = [
        name for name in primary_key_columns if isinstance(pk_dtypes[name], dt.Optional)
    ]
    if nullable_pks:
        raise ValueError(
            f"pw.io.mysql.read primary_key column(s) {nullable_pks} are declared "
            "nullable; primary-key columns must be non-nullable so the connector "
            "can derive a unique row identity. NULL values would collide on the "
            "same Pathway key and change tracking would silently merge unrelated "
            "rows."
        )

View on GitHub (pinned to fa2f74a464)

Solutions

  1. Mark the MySQL table's primary-key column(s) in the Pathway schema with pw.column_definition(primary_key=True).
  2. For a composite MySQL primary key, mark every column of the composite.
  3. If no natural key exists, pick a unique NOT NULL column (e.g. an AUTO_INCREMENT id) and mark it.

Example fix

# before
class MySchema(pw.Schema):
    id: int
    payload: str

# after
class MySchema(pw.Schema):
    id: int = pw.column_definition(primary_key=True)
    payload: str
Defensive patterns

Strategy: validation

Validate before calling

assert schema.primary_key_columns(), (
    "pw.io.mysql.read requires primary_key=True on the key column(s)"
)

Type guard

def is_keyed_schema(schema) -> bool:
    return bool(schema.primary_key_columns())

Try / catch

try:
    table = pw.io.mysql.read(conn, table_name, schema=MySchema)
except ValueError as e:
    if "primary key column" in str(e):
        raise SystemExit("Mark the MySQL table's PK with pw.column_definition(primary_key=True)") from e
    raise

Prevention

When it happens

Trigger: Calling pw.io.mysql.read(connection_string, table_name, schema=MySchema) where MySchema declares no column with primary_key=True.

Common situations: Reusing a schema written for csv/jsonlines input where keys are optional; assuming the connector infers the key from the MySQL table DDL; quick-start schemas copied from tutorials without key annotations.

Related errors


AI-assisted analysis of pathwaycom/pathway@fa2f74a464 (2026-08-15). Data as JSON: /api/errors/7e9fde7b65a416ee. Report an issue: GitHub.