Skip to content

Commit 0f5b514

Browse files
Fix BigQuery Storage Write API stream count for bounded writes (#38776)
* Fix BigQuery Storage Write API stream count for bounded writes
1 parent aaf677b commit 0f5b514

5 files changed

Lines changed: 18 additions & 10 deletions

File tree

sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/providers/BigQueryStorageWriteApiSchemaTransformProvider.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,11 +179,11 @@ public PCollectionRowTuple expand(PCollectionRowTuple input) {
179179
PCollection<Row> inputRows = input.getSinglePCollection();
180180

181181
BigQueryIO.Write<Row> write = createStorageWriteApiTransform(inputRows.getSchema());
182+
int numStreams = configuration.getNumStreams() == null ? 0 : configuration.getNumStreams();
182183

183184
if (inputRows.isBounded() == IsBounded.UNBOUNDED) {
184185
Long triggeringFrequency = configuration.getTriggeringFrequencySeconds();
185186
Boolean autoSharding = configuration.getAutoSharding();
186-
int numStreams = configuration.getNumStreams() == null ? 0 : configuration.getNumStreams();
187187

188188
boolean useAtLeastOnceSemantics =
189189
configuration.getUseAtLeastOnceSemantics() != null
@@ -197,12 +197,13 @@ public PCollectionRowTuple expand(PCollectionRowTuple input) {
197197
: Duration.standardSeconds(triggeringFrequency));
198198
}
199199
// set num streams if specified, otherwise default to autoSharding
200-
if (numStreams > 0) {
201-
write = write.withNumStorageWriteApiStreams(numStreams);
202-
} else if (autoSharding == null || autoSharding) {
200+
if (numStreams == 0 && (autoSharding == null || autoSharding)) {
203201
write = write.withAutoSharding();
204202
}
205203
}
204+
if (numStreams > 0) {
205+
write = write.withNumStorageWriteApiStreams(numStreams);
206+
}
206207

207208
Schema inputSchema = inputRows.getSchema();
208209

sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/providers/BigQueryWriteConfiguration.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ public void validate() {
101101

102102
Boolean autoSharding = getAutoSharding();
103103
Integer numStreams = getNumStreams();
104+
if (numStreams != null) {
105+
checkArgument(
106+
numStreams >= 0,
107+
invalidConfigMessage + "numStreams must be non-negative, but was: %s",
108+
numStreams);
109+
}
104110
if (autoSharding != null && autoSharding && numStreams != null) {
105111
checkArgument(
106112
numStreams == 0,
@@ -152,8 +158,7 @@ public static Builder builder() {
152158
public abstract Boolean getAutoSharding();
153159

154160
@SchemaFieldDescription(
155-
"Specifies the number of write streams that the Storage API sink will use. "
156-
+ "This parameter is only applicable when writing unbounded data.")
161+
"Specifies the number of write streams that the Storage API sink will use.")
157162
@Nullable
158163
public abstract Integer getNumStreams();
159164

sdks/java/io/google-cloud-platform/src/test/java/org/apache/beam/sdk/io/gcp/bigquery/providers/BigQueryStorageWriteApiSchemaTransformProviderTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,10 @@ public void testInvalidConfig() {
122122
Arrays.asList(
123123
BigQueryWriteConfiguration.builder()
124124
.setTable("project:dataset.table")
125-
.setCreateDisposition("INVALID_DISPOSITION"));
125+
.setCreateDisposition("INVALID_DISPOSITION"),
126+
BigQueryWriteConfiguration.builder()
127+
.setTable("project:dataset.table")
128+
.setNumStreams(-1));
126129

127130
for (BigQueryWriteConfiguration.Builder config : invalidConfigs) {
128131
assertThrows(

sdks/python/apache_beam/io/gcp/bigquery.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2155,8 +2155,7 @@ def __init__(
21552155
all of FILE_LOADS, STREAMING_INSERTS, and STORAGE_WRITE_API. Only
21562156
applicable to unbounded input.
21572157
num_storage_api_streams: Specifies the number of write streams that the
2158-
Storage API sink will use. This parameter is only applicable when
2159-
writing unbounded data.
2158+
Storage API sink will use.
21602159
ignore_unknown_columns: Accept rows that contain values that do not match
21612160
the schema. The unknown values are ignored. Default is False,
21622161
which treats unknown values as errors. This option is only valid for

website/www/site/content/en/documentation/io/built-in/google-bigquery.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -855,7 +855,7 @@ pipeline uses. You can set it explicitly on the transform via
855855
[`withNumStorageWriteApiStreams`](https://beam.apache.org/releases/javadoc/current/org/apache/beam/sdk/io/gcp/bigquery/BigQueryIO.Write.html#withNumStorageWriteApiStreams-int-)
856856
or provide the `numStorageWriteApiStreams` option to the pipeline as defined in
857857
[`BigQueryOptions`](https://beam.apache.org/releases/javadoc/current/org/apache/beam/sdk/io/gcp/bigquery/BigQueryOptions.html).
858-
Please note this is only supported for streaming pipelines.
858+
Fixed stream counts can be used with both batch and streaming pipelines.
859859

860860
Triggering frequency determines how soon the data is visible for querying in
861861
BigQuery. You can explicitly set it via

0 commit comments

Comments
 (0)