{"record":{"id":"b5b2eae9986ea7db","repo":"apache/beam","slug":"columns-are-required-with-the-table-name","errorCode":null,"errorMessage":"Columns are required with the table name.","messagePattern":"Columns are required with the table name\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/gcp/experimental/spannerio.py","lineNumber":755,"sourceCode":"    \"\"\"\n    self._configuration = _BeamSpannerConfiguration(\n        project=project_id,\n        instance=instance_id,\n        database=database_id,\n        table=table,\n        query_name=query_name,\n        credentials=credentials,\n        pool=pool,\n        snapshot_read_timestamp=read_timestamp,\n        snapshot_exact_staleness=exact_staleness)\n\n    self._read_operations = read_operations\n    self._transaction = transaction\n\n    if self._read_operations is None:\n      if table is not None:\n        if columns is None:\n          raise ValueError(\"Columns are required with the table name.\")\n        self._read_operations = [\n            ReadOperation.table(\n                table=table, columns=columns, index=index, keyset=keyset)\n        ]\n      elif sql is not None:\n        self._read_operations = [\n            ReadOperation.query(\n                sql=sql, params=params, param_types=param_types)\n        ]\n\n  def expand(self, pbegin):\n    if self._read_operations is not None and isinstance(pbegin, PBegin):\n      pcoll = pbegin.pipeline | Create(self._read_operations)\n    elif not isinstance(pbegin, PBegin):\n      if self._read_operations is not None:\n        raise ValueError(\n            \"Read operation in the constructor only works with \"\n            \"the root of the pipeline.\")","sourceCodeStart":737,"sourceCodeEnd":773,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/gcp/experimental/spannerio.py#L737-L773","documentation":"SpannerIO's read connector allows specifying just a table name for convenience, but a table read without a column list has no defined projection, so __init__ raises ValueError requiring columns whenever table is given (and no explicit read_operations were supplied).","triggerScenarios":"Calling spannerio.Read(project_id, instance_id, database_id, table='Users') without columns, when read_operations is None; also passing table with sql or omitting columns in kwargs.","commonSituations":"Developers expect SELECT * semantics and pass only a table name; code refactors drop the columns list; config-driven pipelines read a table name from options but forget the columns option.","solutions":["Provide the columns list alongside table: spannerio.Read(..., table='Users', columns=['id', 'name']).","Alternatively pass sql='SELECT * FROM Users' instead of table.","Or construct read_operations explicitly with ReadOperation.table(..., columns=[...]) and pass that.","Make columns a required pipeline option when the table option is set."],"exampleFix":"// before\nread = spannerio.Read(project_id, instance_id, database_id, table='Users')\n// after\nread = spannerio.Read(project_id, instance_id, database_id,\n                     table='Users', columns=['id', 'name', 'email'])","handlingStrategy":"validation","validationCode":"if table is not None and not columns:\n    raise ValueError('columns is required when reading by table name')","typeGuard":null,"tryCatchPattern":"try:\n    read = spannerio.Read(project_id, instance_id, database_id, table=table, columns=columns)\nexcept ValueError as e:\n    if 'Columns are required' in str(e):\n        raise RuntimeError(f'Specify columns for table {table!r}') from e\n    raise","preventionTips":["Treat table and columns as a paired configuration","Prefer sql='SELECT * FROM table' if you truly want all columns","Make columns a required pipeline option whenever table is set"],"tags":["google-cloud-spanner","missing-argument","apache-beam"],"backgroundTag":"missing-required-argument","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}