[Feature Request]: Allow non-identifier column names in Python Row
Los mantenedores suelen responder en 1 día
@schizophrenicmaniac ya está trabajando en esto.
Desde el 20/10/2026.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 48/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Área
- backend, data-engineering
Línea de trabajo
Start in sdks/python/apache_beam/typehints/schemas.py at SchemaTranslation.named_tuple_from_schema, then read the RowCoder construction path in sdks/python/apache_beam/coders/coder_impl.py and the tests covering schema translation and row coding. Reproduce the failure with the supplied schema containing EXPR$0 and 31-60 days; done means Python can construct and encode or decode rows while preserving those field names.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
What would you like to happen?
What happened?
In the Beam Portability API (schema.proto) and the Java SDK (org.apache.beam.sdk.schemas.Schema / org.apache.beam.sdk.values.Row), schema field names can be arbitrary strings. For example, Calcite SQL (SqlTransform) routinely produces output schemas with column names such as:
- Unaliased expression names:
EXPR$0,EXPR$1 - Quoted SQL column aliases containing spaces, punctuation, or leading digits:
>120 days,31-60 days,91-120 days(e.g., TPC-DS Q62, Q99) - Python reserved keywords:
from,class,return
However, when a schema is decoded in the Python SDK (for instance, when receiving the output of cross-language SqlTransform or any portable RowCoder), SchemaTranslation.named_tuple_from_schema (sdks/python/apache_beam/typehints/schemas.py) attempts to construct a typing.NamedTuple (or dataclasses.make_dataclass when a field starts with _, thanks to a recent patch in #40542):
if any(name.startswith('_') for name, _ in subfields):
user_type = dataclasses.make_dataclass(
type_name,
subfields,
namespace={'_asdict': _dataclass_asdict},
frozen=True)
else:
user_type = NamedTuple(type_name, subfields)
Both typing.NamedTuple and dataclasses.make_dataclass enforce strict Python identifier rules (name.isidentifier() and not keyword.iskeyword(name)), causing RowCoder initialization to fail with:
ValueError: Type names and field names must be valid identifiers: 'EXPR$0'
or:
TypeError: Field names must be valid identifiers: '31-60 days'
Why is this a feature gap?
- Cross-language incompatibility: A valid
PCollection<Row>produced by a Java transform (such asSqlTransformor xlang I/O connectors) cannot be consumed in Python if any column name is not a strict Python identifier. - Incremental workarounds in
named_tuple_from_schema: Previously,dataclasses.make_dataclasswas added as a fallback specifically for leading-underscore column names like_change_type(CDC metadata), becauseNamedTuplerejected them. However,make_dataclassstill rejects non-identifier characters ($, spaces,-,>), leading digits, dunder names, and Python keywords. - Python runtime already supports arbitrary attribute names:
RowCoderImpl(sdks/python/apache_beam/coders/coder_impl.py) encodes and decodes fields usinggetattr(value, name)and positional constructionself.constructor(*values). In Python,getattrand class namespaces (type(name, (tuple,), namespace)withproperty(operator.itemgetter(i))) work with arbitrary string keys, not just valid Python identifiers.
Steps to Reproduce
from apache_beam.coders import RowCoder
from apache_beam.portability.api import schema_pb2
schema = schema_pb2.Schema(
id="sql_expr_schema",
fields=[
schema_pb2.Field(
name="EXPR$0",
type=schema_pb2.FieldType(atomic_type=schema_pb2.INT64)),
schema_pb2.Field(
name="31-60 days",
type=schema_pb2.FieldType(atomic_type=schema_pb2.INT64)),
])
coder = RowCoder(schema) # Raises ValueError: Type names and field names must be valid identifiers: 'EXPR$0'
Proposed Solution
In SchemaTranslation.named_tuple_from_schema (sdks/python/apache_beam/typehints/schemas.py), when any field name in subfields is not a valid Python identifier or is a Python keyword (i.e., rejected by both NamedTuple and make_dataclass), construct a dynamic tuple-backed row class via type(type_name, (tuple,), namespace) that:
- Sets
_fields = tuple(name for name, _ in subfields)and__annotations__ = dict(subfields)somatch_is_named_tuple()andRowTypeConstraint.from_user_type()continue to work seamlessly. - Binds
property(operator.itemgetter(i))in the class dictionary for each field name (which Python allows for arbitrary string keys, sogetattr(row, "EXPR$0")andgetattr(row, "31-60 days")work in O(1) time). - Implements
__new__(cls, *args, **kwargs),_asdict(), and__repr__()matchingNamedTuplesemantics while preserving the exact portable schema field names.
Issue Priority
Priority: 2 (default / most feature requests should be filed as P2)
Issue Components
- Component: Python SDK
- Component: Java SDK
- Component: Go SDK
- Component: Typescript SDK
- Component: IO connector
- Component: Beam YAML
- Component: Beam examples
- Component: Beam playground
- Component: Beam katas
- Component: Website
- Component: Infrastructure
- Component: Spark Runner
- Component: Flink Runner
- Component: Prism Runner
- Component: Twister2 Runner
- Component: Hazelcast Jet Runner
- Component: Google Cloud Dataflow Runner
- Lenguaje dominante
- Java
- Estrellas
- 8.7k
- Forks
- 4.8k
- Merge medio
- 2 d 12 h
- PR fusionados (30 d)
- 371
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de apache/beam
-
Release notes links wrongAbiertoawaiting triage bug P3
Dificultad 1/5 Menos de una hora Aptitud para principiantes 67/100
apache/beam#41197 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
[Bug]: [Python] WriteToJson silently rounds floats to 10 decimal placesPosiblemente ocupada @Abhi2939 la tomó hace 2 días. Abiertoio P2 python yaml
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
apache/beam#41102 · 4 comentarios ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
apache/beam#39624 · 2 reacciones ·
Los mantenedores suelen responder en 1 día
-
[Bug]: PubsubIO used in batch incorrect batch cutoff sizePosiblemente ocupada @1fanwang la tomó hace 79 días. Abiertobug io P3 pinned pubsub
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
apache/beam#28011 · 4 comentarios ·
Los mantenedores suelen responder en 1 día
-
build P3 sub-task
Dificultad 1/5 Menos de una hora Aptitud para principiantes 68/100
Los mantenedores suelen responder en 1 día
Todos los issues de apache/beam
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
spAnser/reacharound#38 ·
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 89/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
-
Type: Bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 83/100
MovingBlocks/Terasology#5415 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100