google-cloud-bigquery 1.14.0 → 1.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/AUTHENTICATION.md +17 -54
  3. data/CHANGELOG.md +377 -0
  4. data/CONTRIBUTING.md +328 -116
  5. data/LOGGING.md +1 -1
  6. data/OVERVIEW.md +21 -20
  7. data/TROUBLESHOOTING.md +2 -8
  8. data/lib/google/cloud/bigquery/argument.rb +197 -0
  9. data/lib/google/cloud/bigquery/convert.rb +155 -173
  10. data/lib/google/cloud/bigquery/copy_job.rb +74 -26
  11. data/lib/google/cloud/bigquery/credentials.rb +5 -12
  12. data/lib/google/cloud/bigquery/data.rb +109 -18
  13. data/lib/google/cloud/bigquery/dataset/access.rb +474 -52
  14. data/lib/google/cloud/bigquery/dataset/list.rb +7 -13
  15. data/lib/google/cloud/bigquery/dataset/tag.rb +67 -0
  16. data/lib/google/cloud/bigquery/dataset.rb +1044 -287
  17. data/lib/google/cloud/bigquery/external/avro_source.rb +107 -0
  18. data/lib/google/cloud/bigquery/external/bigtable_source/column.rb +404 -0
  19. data/lib/google/cloud/bigquery/external/bigtable_source/column_family.rb +945 -0
  20. data/lib/google/cloud/bigquery/external/bigtable_source.rb +230 -0
  21. data/lib/google/cloud/bigquery/external/csv_source.rb +481 -0
  22. data/lib/google/cloud/bigquery/external/data_source.rb +771 -0
  23. data/lib/google/cloud/bigquery/external/json_source.rb +170 -0
  24. data/lib/google/cloud/bigquery/external/parquet_source.rb +148 -0
  25. data/lib/google/cloud/bigquery/external/sheets_source.rb +166 -0
  26. data/lib/google/cloud/bigquery/external.rb +50 -2256
  27. data/lib/google/cloud/bigquery/extract_job.rb +226 -61
  28. data/lib/google/cloud/bigquery/insert_response.rb +1 -3
  29. data/lib/google/cloud/bigquery/job/list.rb +10 -14
  30. data/lib/google/cloud/bigquery/job.rb +289 -14
  31. data/lib/google/cloud/bigquery/load_job.rb +810 -136
  32. data/lib/google/cloud/bigquery/model/list.rb +5 -9
  33. data/lib/google/cloud/bigquery/model.rb +247 -16
  34. data/lib/google/cloud/bigquery/policy.rb +432 -0
  35. data/lib/google/cloud/bigquery/project/list.rb +6 -11
  36. data/lib/google/cloud/bigquery/project.rb +509 -250
  37. data/lib/google/cloud/bigquery/query_job.rb +594 -128
  38. data/lib/google/cloud/bigquery/routine/list.rb +165 -0
  39. data/lib/google/cloud/bigquery/routine.rb +1227 -0
  40. data/lib/google/cloud/bigquery/schema/field.rb +413 -63
  41. data/lib/google/cloud/bigquery/schema.rb +221 -48
  42. data/lib/google/cloud/bigquery/service.rb +204 -112
  43. data/lib/google/cloud/bigquery/standard_sql.rb +269 -53
  44. data/lib/google/cloud/bigquery/table/async_inserter.rb +86 -43
  45. data/lib/google/cloud/bigquery/table/list.rb +6 -11
  46. data/lib/google/cloud/bigquery/table.rb +1470 -377
  47. data/lib/google/cloud/bigquery/time.rb +6 -0
  48. data/lib/google/cloud/bigquery/version.rb +1 -1
  49. data/lib/google/cloud/bigquery.rb +4 -6
  50. data/lib/google-cloud-bigquery.rb +14 -13
  51. metadata +66 -38
@@ -17,6 +17,24 @@ require "google/cloud/bigquery/encryption_configuration"
17
17
  module Google
18
18
  module Cloud
19
19
  module Bigquery
20
+ module OperationType
21
+ # Different operation types supported in table copy job.
22
+ # https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#operationtype
23
+
24
+ # The source and destination table have the same table type.
25
+ COPY = "COPY".freeze
26
+
27
+ # The source table type is TABLE and the destination table type is SNAPSHOT.
28
+ SNAPSHOT = "SNAPSHOT".freeze
29
+
30
+ # The source table type is SNAPSHOT and the destination table type is TABLE.
31
+ RESTORE = "RESTORE".freeze
32
+
33
+ # The source and destination table have the same table type, but only bill for
34
+ # unique data.
35
+ CLONE = "CLONE".freeze
36
+ end
37
+
20
38
  ##
21
39
  # # CopyJob
22
40
  #
@@ -46,27 +64,35 @@ module Google
46
64
  # The table from which data is copied. This is the table on
47
65
  # which {Table#copy_job} was called.
48
66
  #
67
+ # @param [String] view Specifies the view that determines which table information is returned.
68
+ # By default, basic table information and storage statistics (STORAGE_STATS) are returned.
69
+ # Accepted values include `:unspecified`, `:basic`, `:storage`, and
70
+ # `:full`. For more information, see [BigQuery Classes](@todo: Update the link).
71
+ # The default value is the `:unspecified` view type.
72
+ #
49
73
  # @return [Table] A table instance.
50
74
  #
51
- def source
75
+ def source view: nil
52
76
  table = @gapi.configuration.copy.source_table
53
77
  return nil unless table
54
- retrieve_table table.project_id,
55
- table.dataset_id,
56
- table.table_id
78
+ retrieve_table table.project_id, table.dataset_id, table.table_id, metadata_view: view
57
79
  end
58
80
 
59
81
  ##
60
82
  # The table to which data is copied.
61
83
  #
84
+ # @param [String] view Specifies the view that determines which table information is returned.
85
+ # By default, basic table information and storage statistics (STORAGE_STATS) are returned.
86
+ # Accepted values include `:unspecified`, `:basic`, `:storage`, and
87
+ # `:full`. For more information, see [BigQuery Classes](@todo: Update the link).
88
+ # The default value is the `:unspecified` view type.
89
+ #
62
90
  # @return [Table] A table instance.
63
91
  #
64
- def destination
92
+ def destination view: nil
65
93
  table = @gapi.configuration.copy.destination_table
66
94
  return nil unless table
67
- retrieve_table table.project_id,
68
- table.dataset_id,
69
- table.table_id
95
+ retrieve_table table.project_id, table.dataset_id, table.table_id, metadata_view: view
70
96
  end
71
97
 
72
98
  ##
@@ -139,9 +165,7 @@ module Google
139
165
  #
140
166
  # @!group Attributes
141
167
  def encryption
142
- EncryptionConfiguration.from_gapi(
143
- @gapi.configuration.copy.destination_encryption_configuration
144
- )
168
+ EncryptionConfiguration.from_gapi @gapi.configuration.copy.destination_encryption_configuration
145
169
  end
146
170
 
147
171
  ##
@@ -150,6 +174,7 @@ module Google
150
174
  ##
151
175
  # @private Create an Updater object.
152
176
  def initialize gapi
177
+ super()
153
178
  @gapi = gapi
154
179
  end
155
180
 
@@ -158,11 +183,12 @@ module Google
158
183
  #
159
184
  # @return [Google::Cloud::Bigquery::CopyJob::Updater] A job
160
185
  # configuration object for setting copy options.
161
- def self.from_options service, source, target, options = {}
186
+ def self.from_options service, source, target, options
162
187
  job_ref = service.job_ref_from options[:job_id], options[:prefix]
163
188
  copy_cfg = Google::Apis::BigqueryV2::JobConfigurationTableCopy.new(
164
189
  source_table: source,
165
- destination_table: target
190
+ destination_table: target,
191
+ operation_type: options[:operation_type]
166
192
  )
167
193
  req = Google::Apis::BigqueryV2::Job.new(
168
194
  job_reference: job_ref,
@@ -227,8 +253,7 @@ module Google
227
253
  #
228
254
  # @!group Attributes
229
255
  def create= new_create
230
- @gapi.configuration.copy.update! \
231
- create_disposition: Convert.create_disposition(new_create)
256
+ @gapi.configuration.copy.update! create_disposition: Convert.create_disposition(new_create)
232
257
  end
233
258
 
234
259
  ##
@@ -248,8 +273,7 @@ module Google
248
273
  #
249
274
  # @!group Attributes
250
275
  def write= new_write
251
- @gapi.configuration.copy.update! \
252
- write_disposition: Convert.write_disposition(new_write)
276
+ @gapi.configuration.copy.update! write_disposition: Convert.write_disposition(new_write)
253
277
  end
254
278
 
255
279
  ##
@@ -273,27 +297,51 @@ module Google
273
297
  #
274
298
  # @!group Attributes
275
299
  def encryption= val
276
- @gapi.configuration.copy.update!(
277
- destination_encryption_configuration: val.to_gapi
278
- )
300
+ @gapi.configuration.copy.update! destination_encryption_configuration: val.to_gapi
279
301
  end
280
302
 
281
303
  ##
282
304
  # Sets the labels to use for the job.
283
305
  #
284
306
  # @param [Hash] value A hash of user-provided labels associated with
285
- # the job. You can use these to organize and group your jobs. Label
286
- # keys and values can be no longer than 63 characters, can only
287
- # contain lowercase letters, numeric characters, underscores and
288
- # dashes. International characters are allowed. Label values are
289
- # optional. Label keys must start with a letter and each label in
290
- # the list must have a different key.
307
+ # the job. You can use these to organize and group your jobs.
308
+ #
309
+ # The labels applied to a resource must meet the following requirements:
310
+ #
311
+ # * Each resource can have multiple labels, up to a maximum of 64.
312
+ # * Each label must be a key-value pair.
313
+ # * Keys have a minimum length of 1 character and a maximum length of
314
+ # 63 characters, and cannot be empty. Values can be empty, and have
315
+ # a maximum length of 63 characters.
316
+ # * Keys and values can contain only lowercase letters, numeric characters,
317
+ # underscores, and dashes. All characters must use UTF-8 encoding, and
318
+ # international characters are allowed.
319
+ # * The key portion of a label must be unique. However, you can use the
320
+ # same key with multiple resources.
321
+ # * Keys must start with a lowercase letter or international character.
291
322
  #
292
323
  # @!group Attributes
293
324
  def labels= value
294
325
  @gapi.configuration.update! labels: value
295
326
  end
296
327
 
328
+ def cancel
329
+ raise "not implemented in #{self.class}"
330
+ end
331
+
332
+ def rerun!
333
+ raise "not implemented in #{self.class}"
334
+ end
335
+
336
+ def reload!
337
+ raise "not implemented in #{self.class}"
338
+ end
339
+ alias refresh! reload!
340
+
341
+ def wait_until_done!
342
+ raise "not implemented in #{self.class}"
343
+ end
344
+
297
345
  ##
298
346
  # @private Returns the Google API client library version of this job.
299
347
  #
@@ -39,18 +39,11 @@ module Google
39
39
  #
40
40
  class Credentials < Google::Auth::Credentials
41
41
  SCOPE = ["https://www.googleapis.com/auth/bigquery"].freeze
42
- PATH_ENV_VARS = %w[BIGQUERY_CREDENTIALS
43
- GOOGLE_CLOUD_CREDENTIALS
44
- BIGQUERY_KEYFILE
45
- GOOGLE_CLOUD_KEYFILE
46
- GCLOUD_KEYFILE].freeze
47
- JSON_ENV_VARS = %w[BIGQUERY_CREDENTIALS_JSON
48
- GOOGLE_CLOUD_CREDENTIALS_JSON
49
- BIGQUERY_KEYFILE_JSON
50
- GOOGLE_CLOUD_KEYFILE_JSON
51
- GCLOUD_KEYFILE_JSON].freeze
52
- DEFAULT_PATHS = \
53
- ["~/.config/gcloud/application_default_credentials.json"].freeze
42
+ PATH_ENV_VARS = ["BIGQUERY_CREDENTIALS", "GOOGLE_CLOUD_CREDENTIALS", "BIGQUERY_KEYFILE", "GOOGLE_CLOUD_KEYFILE",
43
+ "GCLOUD_KEYFILE"].freeze
44
+ JSON_ENV_VARS = ["BIGQUERY_CREDENTIALS_JSON", "GOOGLE_CLOUD_CREDENTIALS_JSON", "BIGQUERY_KEYFILE_JSON",
45
+ "GOOGLE_CLOUD_KEYFILE_JSON", "GCLOUD_KEYFILE_JSON"].freeze
46
+ DEFAULT_PATHS = ["~/.config/gcloud/application_default_credentials.json"].freeze
54
47
  end
55
48
  end
56
49
  end
@@ -41,9 +41,12 @@ module Google
41
41
  #
42
42
  # data.count # 100000
43
43
  # data.total # 164656
44
+ #
45
+ # # Iterate over the first page of results
44
46
  # data.each do |row|
45
47
  # puts row[:word]
46
48
  # end
49
+ # # Retrieve the next page of results
47
50
  # data = data.next if data.next?
48
51
  #
49
52
  class Data < DelegateClass(::Array)
@@ -117,9 +120,12 @@ module Google
117
120
  #
118
121
  # data.count # 100000
119
122
  # data.total # 164656
123
+ #
124
+ # # Iterate over the first page of results
120
125
  # data.each do |row|
121
126
  # puts row[:word]
122
127
  # end
128
+ # # Retrieve the next page of results
123
129
  # data = data.next if data.next?
124
130
  #
125
131
  def total
@@ -200,10 +206,34 @@ module Google
200
206
  schema.headers
201
207
  end
202
208
 
209
+ ##
210
+ # The types of the fields in the data, obtained from the schema of the
211
+ # table from which the data was read. Types use the same format as the
212
+ # optional query parameter types.
213
+ #
214
+ # @return [Hash] A hash with field names as keys, and types as values.
215
+ #
216
+ # @example
217
+ # require "google/cloud/bigquery"
218
+ #
219
+ # bigquery = Google::Cloud::Bigquery.new
220
+ # dataset = bigquery.dataset "my_dataset"
221
+ # table = dataset.table "my_table"
222
+ #
223
+ # data = table.data
224
+ #
225
+ # data.param_types
226
+ #
227
+ def param_types
228
+ schema.param_types
229
+ end
230
+
203
231
  ##
204
232
  # The type of query statement, if valid. Possible values (new values
205
233
  # might be added in the future):
206
234
  #
235
+ # * "ALTER_TABLE": DDL statement, see [Using Data Definition Language
236
+ # Statements](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language)
207
237
  # * "CREATE_MODEL": DDL statement, see [Using Data Definition Language
208
238
  # Statements](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language)
209
239
  # * "CREATE_TABLE": DDL statement, see [Using Data Definition Language
@@ -227,8 +257,7 @@ module Google
227
257
  # @return [String, nil] The type of query statement.
228
258
  #
229
259
  def statement_type
230
- return nil unless job_gapi && job_gapi.statistics.query
231
- job_gapi.statistics.query.statement_type
260
+ job_gapi&.statistics&.query&.statement_type
232
261
  end
233
262
 
234
263
  ##
@@ -249,8 +278,16 @@ module Google
249
278
  # data.ddl? #=> true
250
279
  #
251
280
  def ddl?
252
- %w[CREATE_MODEL CREATE_TABLE CREATE_TABLE_AS_SELECT CREATE_VIEW \
253
- DROP_MODEL DROP_TABLE DROP_VIEW].include? statement_type
281
+ [
282
+ "ALTER_TABLE",
283
+ "CREATE_MODEL",
284
+ "CREATE_TABLE",
285
+ "CREATE_TABLE_AS_SELECT",
286
+ "CREATE_VIEW",
287
+ "DROP_MODEL",
288
+ "DROP_TABLE",
289
+ "DROP_VIEW"
290
+ ].include? statement_type
254
291
  end
255
292
 
256
293
  ##
@@ -273,7 +310,12 @@ module Google
273
310
  # data.dml? #=> true
274
311
  #
275
312
  def dml?
276
- %w[INSERT UPDATE MERGE DELETE].include? statement_type
313
+ [
314
+ "INSERT",
315
+ "UPDATE",
316
+ "MERGE",
317
+ "DELETE"
318
+ ].include? statement_type
277
319
  end
278
320
 
279
321
  ##
@@ -292,8 +334,22 @@ module Google
292
334
  # @return [String, nil] The DDL operation performed.
293
335
  #
294
336
  def ddl_operation_performed
295
- return nil unless job_gapi && job_gapi.statistics.query
296
- job_gapi.statistics.query.ddl_operation_performed
337
+ job_gapi&.statistics&.query&.ddl_operation_performed
338
+ end
339
+
340
+ ##
341
+ # The DDL target routine, in reference state. (See {Routine#reference?}.)
342
+ # Present only for `CREATE/DROP FUNCTION/PROCEDURE` queries. (See
343
+ # {#statement_type}.)
344
+ #
345
+ # @return [Google::Cloud::Bigquery::Routine, nil] The DDL target routine, in
346
+ # reference state.
347
+ #
348
+ def ddl_target_routine
349
+ ensure_service!
350
+ routine = job_gapi&.statistics&.query&.ddl_target_routine
351
+ return nil if routine.nil?
352
+ Google::Cloud::Bigquery::Routine.new_reference_from_gapi routine, service
297
353
  end
298
354
 
299
355
  ##
@@ -305,10 +361,9 @@ module Google
305
361
  # reference state.
306
362
  #
307
363
  def ddl_target_table
308
- return nil unless job_gapi && job_gapi.statistics.query
309
364
  ensure_service!
310
- table = job_gapi.statistics.query.ddl_target_table
311
- return nil unless table
365
+ table = job_gapi&.statistics&.query&.ddl_target_table
366
+ return nil if table.nil?
312
367
  Google::Cloud::Bigquery::Table.new_reference_from_gapi table, service
313
368
  end
314
369
 
@@ -320,8 +375,40 @@ module Google
320
375
  # or `nil` if the query is not a DML statement.
321
376
  #
322
377
  def num_dml_affected_rows
323
- return nil unless job_gapi && job_gapi.statistics.query
324
- job_gapi.statistics.query.num_dml_affected_rows
378
+ job_gapi&.statistics&.query&.num_dml_affected_rows
379
+ end
380
+
381
+ ##
382
+ # The number of deleted rows. Present only for DML statements `DELETE`,
383
+ # `MERGE` and `TRUNCATE`. (See {#statement_type}.)
384
+ #
385
+ # @return [Integer, nil] The number of deleted rows, or `nil` if not
386
+ # applicable.
387
+ #
388
+ def deleted_row_count
389
+ job_gapi&.statistics&.query&.dml_stats&.deleted_row_count
390
+ end
391
+
392
+ ##
393
+ # The number of inserted rows. Present only for DML statements `INSERT`
394
+ # and `MERGE`. (See {#statement_type}.)
395
+ #
396
+ # @return [Integer, nil] The number of inserted rows, or `nil` if not
397
+ # applicable.
398
+ #
399
+ def inserted_row_count
400
+ job_gapi&.statistics&.query&.dml_stats&.inserted_row_count
401
+ end
402
+
403
+ ##
404
+ # The number of updated rows. Present only for DML statements `UPDATE`
405
+ # and `MERGE`. (See {#statement_type}.)
406
+ #
407
+ # @return [Integer, nil] The number of updated rows, or `nil` if not
408
+ # applicable.
409
+ #
410
+ def updated_row_count
411
+ job_gapi&.statistics&.query&.dml_stats&.updated_row_count
325
412
  end
326
413
 
327
414
  ##
@@ -342,9 +429,12 @@ module Google
342
429
  #
343
430
  # data.count # 100000
344
431
  # data.total # 164656
432
+ #
433
+ # # Iterate over the first page of results
345
434
  # data.each do |row|
346
435
  # puts row[:word]
347
436
  # end
437
+ # # Retrieve the next page of results
348
438
  # data = data.next if data.next?
349
439
  #
350
440
  def next?
@@ -369,9 +459,12 @@ module Google
369
459
  #
370
460
  # data.count # 100000
371
461
  # data.total # 164656
462
+ #
463
+ # # Iterate over the first page of results
372
464
  # data.each do |row|
373
465
  # puts row[:word]
374
466
  # end
467
+ # # Retrieve the next page of results
375
468
  # data = data.next if data.next?
376
469
  #
377
470
  def next
@@ -437,17 +530,17 @@ module Google
437
530
  # puts row[:word]
438
531
  # end
439
532
  #
440
- def all request_limit: nil
533
+ def all request_limit: nil, &block
441
534
  request_limit = request_limit.to_i if request_limit
442
535
 
443
536
  return enum_for :all, request_limit: request_limit unless block_given?
444
537
 
445
538
  results = self
446
539
  loop do
447
- results.each { |r| yield r }
540
+ results.each(&block)
448
541
  if request_limit
449
542
  request_limit -= 1
450
- break if request_limit < 0
543
+ break if request_limit.negative?
451
544
  end
452
545
  break unless results.next?
453
546
  results = results.next
@@ -458,9 +551,7 @@ module Google
458
551
  # @private New Data from a response object.
459
552
  def self.from_gapi_json gapi_json, table_gapi, job_gapi, service
460
553
  rows = gapi_json[:rows] || []
461
- unless rows.empty?
462
- rows = Convert.format_rows rows, table_gapi.schema.fields
463
- end
554
+ rows = Convert.format_rows rows, table_gapi.schema.fields unless rows.empty?
464
555
 
465
556
  data = new rows
466
557
  data.table_gapi = table_gapi