google-cloud-bigquery 1.26.0 → 1.29.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c2f8d8d7a564df2c916cced8adf4c0b621a1e11250a3a04decfce08995a4a24
4
- data.tar.gz: 57bbda27d4c54e0522b564b8cdc62fb5e9dce8b26c91d3f0604c624ff113f057
3
+ metadata.gz: 46f8452c3539550b91ccbde1577ca5e9d7f0d7ad39976a92103590f919d23d3b
4
+ data.tar.gz: 62d2d147f332f0b0d8804eb08f7e5030b45b9068b0abb27e77987c04b670188f
5
5
  SHA512:
6
- metadata.gz: f445a86a5435cafc236d82faf91df46a06c6cee8612d8e6c4011450c93b73b61a883510909c6bb25e72516ae1a57c8a605736d82e0b63f0b10ad25cab90a1280
7
- data.tar.gz: 43423f2bea5cea82c6c19bcf639bfb690f4718b0450140d299616ece59b147258ef877cafbc17b99c68274c310a0cd0123ae6b6db0b37bba2fb08be0395837f0
6
+ metadata.gz: e53218c1b8a8b8ce69463a78f29d27899308edb1a7c383d8b60b09080a1508b5ecb4a29f7527ebaed9c8bbdd080a2c3bf0b4a637e027aaae0c9e592c95979617
7
+ data.tar.gz: f3665ef531ed461202e9cc58214d7b7d386a2e7ab1dbe990609d5414eb2e76f1ec05ab9f54333b578c69329cd5b1da254bc1f06639ec4c82154c0db625dc40db
data/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # Release History
2
2
 
3
+ ### 1.29.0 / 2021-03-10
4
+
5
+ #### Features
6
+
7
+ * Drop support for Ruby 2.4 and add support for Ruby 3.0
8
+
9
+ ### 1.28.0 / 2021-03-09
10
+
11
+ #### Features
12
+
13
+ * Add Materialized View support
14
+ * Add Dataset#create_materialized_view
15
+ * Add Table#materialized_view?
16
+ * Add Table#enable_refresh?
17
+ * Add Table#enable_refresh=
18
+ * Add Table#last_refresh_time
19
+ * Add Table#refresh_interval_ms
20
+ * Add Table#refresh_interval_ms=
21
+
22
+ ### 1.27.0 / 2021-02-10
23
+
24
+ #### Features
25
+
26
+ * Add Job#reservation_usage
27
+ * Add Routine#determinism_level
28
+ * Add Routine#determinism_level
29
+ * Add Routine#determinism_level=
30
+ * Add Routine#determinism_level_deterministic?
31
+ * Add Routine#determinism_level_not_deterministic?
32
+ * Add Routine::Updater#determinism_level=
33
+
3
34
  ### 1.26.0 / 2021-01-13
4
35
 
5
36
  #### Features
data/CONTRIBUTING.md CHANGED
@@ -24,7 +24,7 @@ be able to accept your pull requests.
24
24
  In order to use the google-cloud-bigquery console and run the project's tests,
25
25
  there is a small amount of setup:
26
26
 
27
- 1. Install Ruby. google-cloud-bigquery requires Ruby 2.4+. You may choose to
27
+ 1. Install Ruby. google-cloud-bigquery requires Ruby 2.5+. You may choose to
28
28
  manage your Ruby and gem installations with [RVM](https://rvm.io/),
29
29
  [rbenv](https://github.com/rbenv/rbenv), or
30
30
  [chruby](https://github.com/postmodern/chruby).
data/LOGGING.md CHANGED
@@ -4,7 +4,7 @@ To enable logging for this library, set the logger for the underlying [Google
4
4
  API
5
5
  Client](https://github.com/google/google-api-ruby-client/blob/master/README.md#logging)
6
6
  library. The logger that you set may be a Ruby stdlib
7
- [`Logger`](https://ruby-doc.org/stdlib-2.4.0/libdoc/logger/rdoc/Logger.html) as
7
+ [`Logger`](https://ruby-doc.org/stdlib/libdoc/logger/rdoc/Logger.html) as
8
8
  shown below, or a
9
9
  [`Google::Cloud::Logging::Logger`](https://googleapis.dev/ruby/google-cloud-logging/latest)
10
10
  that will write logs to [Stackdriver
@@ -23,8 +23,6 @@ require "date"
23
23
  module Google
24
24
  module Cloud
25
25
  module Bigquery
26
- # rubocop:disable Metrics/ModuleLength
27
-
28
26
  ##
29
27
  # @private
30
28
  #
@@ -378,8 +376,6 @@ module Google
378
376
  (time_obj.to_i * 1000) + (time_obj.nsec / 1_000_000)
379
377
  end
380
378
  end
381
-
382
- # rubocop:enable Metrics/ModuleLength
383
379
  end
384
380
  end
385
381
  end
@@ -144,6 +144,7 @@ module Google
144
144
  ##
145
145
  # @private Create an Updater object.
146
146
  def initialize gapi
147
+ super()
147
148
  @gapi = gapi
148
149
  end
149
150
 
@@ -482,14 +482,14 @@ module Google
482
482
  # puts row[:word]
483
483
  # end
484
484
  #
485
- def all request_limit: nil
485
+ def all request_limit: nil, &block
486
486
  request_limit = request_limit.to_i if request_limit
487
487
 
488
488
  return enum_for :all, request_limit: request_limit unless block_given?
489
489
 
490
490
  results = self
491
491
  loop do
492
- results.each { |r| yield r }
492
+ results.each(&block)
493
493
  if request_limit
494
494
  request_limit -= 1
495
495
  break if request_limit.negative?
@@ -618,15 +618,17 @@ module Google
618
618
  end
619
619
 
620
620
  ##
621
- # Creates a new [view](https://cloud.google.com/bigquery/docs/views)
622
- # table, which is a virtual table defined by the given SQL query.
621
+ # Creates a new view, which is a virtual table defined by the given SQL query.
623
622
  #
624
- # BigQuery's views are logical views, not materialized views, which
625
- # means that the query that defines the view is re-executed every time
626
- # the view is queried. Queries are billed according to the total amount
623
+ # With BigQuery's logical views, the query that defines the view is re-executed
624
+ # every time the view is queried. Queries are billed according to the total amount
627
625
  # of data in all table fields referenced directly or indirectly by the
628
626
  # top-level query. (See {Table#view?} and {Table#query}.)
629
627
  #
628
+ # For materialized views, see {#create_materialized_view}.
629
+ #
630
+ # @see https://cloud.google.com/bigquery/docs/views Creating views
631
+ #
630
632
  # @param [String] table_id The ID of the view table. The ID must contain
631
633
  # only letters (a-z, A-Z), numbers (0-9), or underscores (_). The
632
634
  # maximum length is 1,024 characters.
@@ -667,7 +669,7 @@ module Google
667
669
  # dataset = bigquery.dataset "my_dataset"
668
670
  #
669
671
  # view = dataset.create_view "my_view",
670
- # "SELECT name, age FROM proj.dataset.users"
672
+ # "SELECT name, age FROM proj.dataset.users"
671
673
  #
672
674
  # @example A name and description can be provided:
673
675
  # require "google/cloud/bigquery"
@@ -676,13 +678,18 @@ module Google
676
678
  # dataset = bigquery.dataset "my_dataset"
677
679
  #
678
680
  # view = dataset.create_view "my_view",
679
- # "SELECT name, age FROM proj.dataset.users",
680
- # name: "My View", description: "This is my view"
681
+ # "SELECT name, age FROM proj.dataset.users",
682
+ # name: "My View", description: "This is my view"
681
683
  #
682
684
  # @!group Table
683
685
  #
684
- def create_view table_id, query, name: nil, description: nil,
685
- standard_sql: nil, legacy_sql: nil, udfs: nil
686
+ def create_view table_id,
687
+ query,
688
+ name: nil,
689
+ description: nil,
690
+ standard_sql: nil,
691
+ legacy_sql: nil,
692
+ udfs: nil
686
693
  use_legacy_sql = Convert.resolve_legacy_sql standard_sql, legacy_sql
687
694
  new_view_opts = {
688
695
  table_reference: Google::Apis::BigqueryV2::TableReference.new(
@@ -698,7 +705,81 @@ module Google
698
705
  user_defined_function_resources: udfs_gapi(udfs)
699
706
  )
700
707
  }.delete_if { |_, v| v.nil? }
701
- new_view = Google::Apis::BigqueryV2::Table.new new_view_opts
708
+ new_view = Google::Apis::BigqueryV2::Table.new(**new_view_opts)
709
+
710
+ gapi = service.insert_table dataset_id, new_view
711
+ Table.from_gapi gapi, service
712
+ end
713
+
714
+ ##
715
+ # Creates a new materialized view.
716
+ #
717
+ # Materialized views are precomputed views that periodically cache results of a query for increased performance
718
+ # and efficiency. BigQuery leverages precomputed results from materialized views and whenever possible reads
719
+ # only delta changes from the base table to compute up-to-date results.
720
+ #
721
+ # Queries that use materialized views are generally faster and consume less resources than queries that retrieve
722
+ # the same data only from the base table. Materialized views are helpful to significantly boost performance of
723
+ # workloads that have the characteristic of common and repeated queries.
724
+ #
725
+ # For logical views, see {#create_view}.
726
+ #
727
+ # @see https://cloud.google.com/bigquery/docs/materialized-views-intro Introduction to materialized views
728
+ #
729
+ # @param [String] table_id The ID of the materialized view table. The ID must contain only letters (a-z, A-Z),
730
+ # numbers (0-9), or underscores (_). The maximum length is 1,024 characters.
731
+ # @param [String] query The query that BigQuery executes when the materialized view is referenced.
732
+ # @param [String] name A descriptive name for the table.
733
+ # @param [String] description A user-friendly description of the table.
734
+ # @param [Boolean] enable_refresh Enable automatic refresh of the materialized view when the base table is
735
+ # updated. Optional. The default value is true.
736
+ # @param [Integer] refresh_interval_ms The maximum frequency in milliseconds at which this materialized view
737
+ # will be refreshed. Optional. The default value is `1_800_000` (30 minutes).
738
+ #
739
+ # @return [Google::Cloud::Bigquery::Table] A new table object.
740
+ #
741
+ # @example
742
+ # require "google/cloud/bigquery"
743
+ #
744
+ # bigquery = Google::Cloud::Bigquery.new
745
+ # dataset = bigquery.dataset "my_dataset"
746
+ #
747
+ # materialized_view = dataset.create_materialized_view "my_materialized_view",
748
+ # "SELECT name, age FROM proj.dataset.users"
749
+ #
750
+ # @example Automatic refresh can be disabled:
751
+ # require "google/cloud/bigquery"
752
+ #
753
+ # bigquery = Google::Cloud::Bigquery.new
754
+ # dataset = bigquery.dataset "my_dataset"
755
+ #
756
+ # materialized_view = dataset.create_materialized_view "my_materialized_view",
757
+ # "SELECT name, age FROM proj.dataset.users",
758
+ # enable_refresh: false
759
+ #
760
+ # @!group Table
761
+ #
762
+ def create_materialized_view table_id,
763
+ query,
764
+ name: nil,
765
+ description: nil,
766
+ enable_refresh: nil,
767
+ refresh_interval_ms: nil
768
+ new_view_opts = {
769
+ table_reference: Google::Apis::BigqueryV2::TableReference.new(
770
+ project_id: project_id,
771
+ dataset_id: dataset_id,
772
+ table_id: table_id
773
+ ),
774
+ friendly_name: name,
775
+ description: description,
776
+ materialized_view: Google::Apis::BigqueryV2::MaterializedViewDefinition.new(
777
+ enable_refresh: enable_refresh,
778
+ query: query,
779
+ refresh_interval_ms: refresh_interval_ms
780
+ )
781
+ }.delete_if { |_, v| v.nil? }
782
+ new_view = Google::Apis::BigqueryV2::Table.new(**new_view_opts)
702
783
 
703
784
  gapi = service.insert_table dataset_id, new_view
704
785
  Table.from_gapi gapi, service
@@ -2500,11 +2581,9 @@ module Google
2500
2581
  create_table table_id do |tbl_updater|
2501
2582
  yield tbl_updater if block_given?
2502
2583
  end
2503
- # rubocop:disable Lint/HandleExceptions
2504
2584
  rescue Google::Cloud::AlreadyExistsError
2585
+ # Do nothing if it already exists
2505
2586
  end
2506
- # rubocop:enable Lint/HandleExceptions
2507
-
2508
2587
  sleep 60
2509
2588
  retry
2510
2589
  end
@@ -2547,7 +2626,7 @@ module Google
2547
2626
  return if attributes.empty?
2548
2627
  ensure_service!
2549
2628
  patch_args = Hash[attributes.map { |attr| [attr, @gapi.send(attr)] }]
2550
- patch_gapi = Google::Apis::BigqueryV2::Dataset.new patch_args
2629
+ patch_gapi = Google::Apis::BigqueryV2::Dataset.new(**patch_args)
2551
2630
  patch_gapi.etag = etag if etag
2552
2631
  @gapi = service.patch_dataset dataset_id, patch_gapi
2553
2632
  end
@@ -2676,12 +2755,11 @@ module Google
2676
2755
 
2677
2756
  def load_local_or_uri file, updater
2678
2757
  job_gapi = updater.to_gapi
2679
- job = if local_file? file
2680
- load_local file, job_gapi
2681
- else
2682
- load_storage file, job_gapi
2683
- end
2684
- job
2758
+ if local_file? file
2759
+ load_local file, job_gapi
2760
+ else
2761
+ load_storage file, job_gapi
2762
+ end
2685
2763
  end
2686
2764
 
2687
2765
  def storage_url? files
@@ -2721,6 +2799,7 @@ module Google
2721
2799
  ##
2722
2800
  # @private Create an Updater object.
2723
2801
  def initialize gapi
2802
+ super()
2724
2803
  @updates = []
2725
2804
  @gapi = gapi
2726
2805
  end
@@ -2756,6 +2835,12 @@ module Google
2756
2835
  raise "not implemented in #{self.class}"
2757
2836
  end
2758
2837
 
2838
+ ##
2839
+ # @raise [RuntimeError] not implemented
2840
+ def create_materialized_view(*)
2841
+ raise "not implemented in #{self.class}"
2842
+ end
2843
+
2759
2844
  ##
2760
2845
  # @raise [RuntimeError] not implemented
2761
2846
  def table(*)
@@ -1194,7 +1194,7 @@ module Google
1194
1194
  @rules.reject!(&find_by_scope_and_value(scope, value))
1195
1195
  # Add new rule for this role, scope, and value
1196
1196
  opts = { role: role, scope => value }
1197
- @rules << Google::Apis::BigqueryV2::Dataset::Access.new(opts)
1197
+ @rules << Google::Apis::BigqueryV2::Dataset::Access.new(**opts)
1198
1198
  end
1199
1199
 
1200
1200
  # @private
@@ -1204,7 +1204,7 @@ module Google
1204
1204
  @rules.reject!(&find_by_scope_and_resource_ref(:routine, value))
1205
1205
  # Add new rule for this role, scope, and value
1206
1206
  opts = { routine: value }
1207
- @rules << Google::Apis::BigqueryV2::Dataset::Access.new(opts)
1207
+ @rules << Google::Apis::BigqueryV2::Dataset::Access.new(**opts)
1208
1208
  end
1209
1209
 
1210
1210
  # @private
@@ -1215,7 +1215,7 @@ module Google
1215
1215
  @rules.reject!(&find_by_scope_and_resource_ref(:view, value))
1216
1216
  # Add new rule for this role, scope, and value
1217
1217
  opts = { view: value }
1218
- @rules << Google::Apis::BigqueryV2::Dataset::Access.new(opts)
1218
+ @rules << Google::Apis::BigqueryV2::Dataset::Access.new(**opts)
1219
1219
  end
1220
1220
 
1221
1221
  # @private
@@ -120,12 +120,12 @@ module Google
120
120
  # puts dataset.name
121
121
  # end
122
122
  #
123
- def all request_limit: nil
123
+ def all request_limit: nil, &block
124
124
  request_limit = request_limit.to_i if request_limit
125
125
  return enum_for :all, request_limit: request_limit unless block_given?
126
126
  results = self
127
127
  loop do
128
- results.each { |r| yield r }
128
+ results.each(&block)
129
129
  if request_limit
130
130
  request_limit -= 1
131
131
  break if request_limit.negative?
@@ -246,6 +246,7 @@ module Google
246
246
  ##
247
247
  # @private Create an Updater object.
248
248
  def initialize gapi
249
+ super()
249
250
  @gapi = gapi
250
251
  end
251
252
 
@@ -263,9 +264,10 @@ module Google
263
264
  extract_config = Google::Apis::BigqueryV2::JobConfigurationExtract.new(
264
265
  destination_uris: Array(storage_urls)
265
266
  )
266
- if source.is_a? Google::Apis::BigqueryV2::TableReference
267
+ case source
268
+ when Google::Apis::BigqueryV2::TableReference
267
269
  extract_config.source_table = source
268
- elsif source.is_a? Google::Apis::BigqueryV2::ModelReference
270
+ when Google::Apis::BigqueryV2::ModelReference
269
271
  extract_config.source_model = source
270
272
  end
271
273
  job = Google::Apis::BigqueryV2::Job.new(
@@ -215,6 +215,17 @@ module Google
215
215
  @gapi.statistics.parent_job_id
216
216
  end
217
217
 
218
+ ##
219
+ # An array containing the job resource usage breakdown by reservation, if present. Reservation usage statistics
220
+ # are only reported for jobs that are executed within reservations. On-demand jobs do not report this data.
221
+ #
222
+ # @return [Array<Google::Cloud::Bigquery::Job::ReservationUsage>, nil] The reservation usage, if present.
223
+ #
224
+ def reservation_usage
225
+ return nil unless @gapi.statistics.reservation_usage
226
+ Array(@gapi.statistics.reservation_usage).map { |g| ReservationUsage.from_gapi g }
227
+ end
228
+
218
229
  ##
219
230
  # The statistics including stack frames for a child job of a script.
220
231
  #
@@ -489,6 +500,30 @@ module Google
489
500
  end
490
501
  end
491
502
 
503
+ ##
504
+ # Represents Job resource usage breakdown by reservation.
505
+ #
506
+ # @attr_reader [String] name The reservation name or "unreserved" for on-demand resources usage.
507
+ # @attr_reader [Fixnum] slot_ms The slot-milliseconds the job spent in the given reservation.
508
+ #
509
+ class ReservationUsage
510
+ attr_reader :name
511
+ attr_reader :slot_ms
512
+
513
+ ##
514
+ # @private Creates a new ReservationUsage instance.
515
+ def initialize name, slot_ms
516
+ @name = name
517
+ @slot_ms = slot_ms
518
+ end
519
+
520
+ ##
521
+ # @private New ReservationUsage from a statistics.reservation_usage value.
522
+ def self.from_gapi gapi
523
+ new gapi.name, gapi.slot_ms
524
+ end
525
+ end
526
+
492
527
  ##
493
528
  # Represents statistics for a child job of a script.
494
529
  #
@@ -537,7 +572,8 @@ module Google
537
572
  # end
538
573
  #
539
574
  class ScriptStatistics
540
- attr_reader :evaluation_kind, :stack_frames
575
+ attr_reader :evaluation_kind
576
+ attr_reader :stack_frames
541
577
 
542
578
  ##
543
579
  # @private Creates a new ScriptStatistics instance.
@@ -547,7 +583,7 @@ module Google
547
583
  end
548
584
 
549
585
  ##
550
- # @private New ScriptStatistics from a statistics.script_statistics object.
586
+ # @private New ScriptStatistics from a statistics.script_statistics value.
551
587
  def self.from_gapi gapi
552
588
  frames = Array(gapi.stack_frames).map { |g| ScriptStackFrame.from_gapi g }
553
589
  new gapi.evaluation_kind, frames
@@ -602,7 +638,11 @@ module Google
602
638
  # end
603
639
  #
604
640
  class ScriptStackFrame
605
- attr_reader :start_line, :start_column, :end_line, :end_column, :text
641
+ attr_reader :start_line
642
+ attr_reader :start_column
643
+ attr_reader :end_line
644
+ attr_reader :end_column
645
+ attr_reader :text
606
646
 
607
647
  ##
608
648
  # @private Creates a new ScriptStackFrame instance.