google-cloud-bigquery 1.21.2
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 +7 -0
- data/.yardopts +16 -0
- data/AUTHENTICATION.md +158 -0
- data/CHANGELOG.md +397 -0
- data/CODE_OF_CONDUCT.md +40 -0
- data/CONTRIBUTING.md +188 -0
- data/LICENSE +201 -0
- data/LOGGING.md +27 -0
- data/OVERVIEW.md +463 -0
- data/TROUBLESHOOTING.md +31 -0
- data/lib/google-cloud-bigquery.rb +139 -0
- data/lib/google/cloud/bigquery.rb +145 -0
- data/lib/google/cloud/bigquery/argument.rb +197 -0
- data/lib/google/cloud/bigquery/convert.rb +383 -0
- data/lib/google/cloud/bigquery/copy_job.rb +316 -0
- data/lib/google/cloud/bigquery/credentials.rb +50 -0
- data/lib/google/cloud/bigquery/data.rb +526 -0
- data/lib/google/cloud/bigquery/dataset.rb +2845 -0
- data/lib/google/cloud/bigquery/dataset/access.rb +1021 -0
- data/lib/google/cloud/bigquery/dataset/list.rb +162 -0
- data/lib/google/cloud/bigquery/encryption_configuration.rb +123 -0
- data/lib/google/cloud/bigquery/external.rb +2432 -0
- data/lib/google/cloud/bigquery/extract_job.rb +368 -0
- data/lib/google/cloud/bigquery/insert_response.rb +180 -0
- data/lib/google/cloud/bigquery/job.rb +657 -0
- data/lib/google/cloud/bigquery/job/list.rb +162 -0
- data/lib/google/cloud/bigquery/load_job.rb +1704 -0
- data/lib/google/cloud/bigquery/model.rb +740 -0
- data/lib/google/cloud/bigquery/model/list.rb +164 -0
- data/lib/google/cloud/bigquery/project.rb +1655 -0
- data/lib/google/cloud/bigquery/project/list.rb +161 -0
- data/lib/google/cloud/bigquery/query_job.rb +1695 -0
- data/lib/google/cloud/bigquery/routine.rb +1108 -0
- data/lib/google/cloud/bigquery/routine/list.rb +165 -0
- data/lib/google/cloud/bigquery/schema.rb +564 -0
- data/lib/google/cloud/bigquery/schema/field.rb +668 -0
- data/lib/google/cloud/bigquery/service.rb +589 -0
- data/lib/google/cloud/bigquery/standard_sql.rb +495 -0
- data/lib/google/cloud/bigquery/table.rb +3340 -0
- data/lib/google/cloud/bigquery/table/async_inserter.rb +520 -0
- data/lib/google/cloud/bigquery/table/list.rb +172 -0
- data/lib/google/cloud/bigquery/time.rb +65 -0
- data/lib/google/cloud/bigquery/version.rb +22 -0
- metadata +297 -0
@@ -0,0 +1,740 @@
|
|
1
|
+
# Copyright 2019 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
|
16
|
+
require "google/cloud/errors"
|
17
|
+
require "google/cloud/bigquery/service"
|
18
|
+
require "google/cloud/bigquery/model/list"
|
19
|
+
require "google/cloud/bigquery/standard_sql"
|
20
|
+
require "google/cloud/bigquery/convert"
|
21
|
+
require "google/apis/bigquery_v2"
|
22
|
+
|
23
|
+
module Google
|
24
|
+
module Cloud
|
25
|
+
module Bigquery
|
26
|
+
##
|
27
|
+
# # Model
|
28
|
+
#
|
29
|
+
# A model in BigQuery ML represents what an ML system has learned from the
|
30
|
+
# training data.
|
31
|
+
#
|
32
|
+
# The following types of models are supported by BigQuery ML:
|
33
|
+
#
|
34
|
+
# * Linear regression for forecasting; for example, the sales of an item
|
35
|
+
# on a given day. Labels are real-valued (they cannot be +/- infinity or
|
36
|
+
# NaN).
|
37
|
+
# * Binary logistic regression for classification; for example,
|
38
|
+
# determining whether a customer will make a purchase. Labels must only
|
39
|
+
# have two possible values.
|
40
|
+
# * Multiclass logistic regression for classification. These models can be
|
41
|
+
# used to predict multiple possible values such as whether an input is
|
42
|
+
# "low-value," "medium-value," or "high-value." Labels can have up to 50
|
43
|
+
# unique values. In BigQuery ML, multiclass logistic regression training
|
44
|
+
# uses a multinomial classifier with a cross entropy loss function.
|
45
|
+
# * K-means clustering for data segmentation (beta); for example,
|
46
|
+
# identifying customer segments. K-means is an unsupervised learning
|
47
|
+
# technique, so model training does not require labels nor split data
|
48
|
+
# for training or evaluation.
|
49
|
+
#
|
50
|
+
# In BigQuery ML, a model can be used with data from multiple BigQuery
|
51
|
+
# datasets for training and for prediction.
|
52
|
+
#
|
53
|
+
# @see https://cloud.google.com/bigquery-ml/docs/bigqueryml-intro
|
54
|
+
# Introduction to BigQuery ML
|
55
|
+
# @see https://cloud.google.com/bigquery-ml/docs/getting-model-metadata
|
56
|
+
# Getting model metadata
|
57
|
+
#
|
58
|
+
# @example
|
59
|
+
# require "google/cloud/bigquery"
|
60
|
+
#
|
61
|
+
# bigquery = Google::Cloud::Bigquery.new
|
62
|
+
# dataset = bigquery.dataset "my_dataset"
|
63
|
+
#
|
64
|
+
# model = dataset.model "my_model"
|
65
|
+
#
|
66
|
+
class Model
|
67
|
+
##
|
68
|
+
# @private The Service object.
|
69
|
+
attr_accessor :service
|
70
|
+
|
71
|
+
##
|
72
|
+
# @private The Google API Client JSON Hash.
|
73
|
+
attr_accessor :gapi_json
|
74
|
+
|
75
|
+
##
|
76
|
+
# @private A Google API Client Model Reference object.
|
77
|
+
attr_reader :reference
|
78
|
+
|
79
|
+
##
|
80
|
+
# @private Create an empty Model object.
|
81
|
+
def initialize
|
82
|
+
@service = nil
|
83
|
+
@gapi_json = nil
|
84
|
+
@reference = nil
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# A unique ID for this model.
|
89
|
+
#
|
90
|
+
# @return [String] The ID must contain only letters (a-z, A-Z), numbers
|
91
|
+
# (0-9), or underscores (_). The maximum length is 1,024 characters.
|
92
|
+
#
|
93
|
+
# @!group Attributes
|
94
|
+
#
|
95
|
+
def model_id
|
96
|
+
return @reference.model_id if reference?
|
97
|
+
@gapi_json[:modelReference][:modelId]
|
98
|
+
end
|
99
|
+
|
100
|
+
##
|
101
|
+
# The ID of the `Dataset` containing this model.
|
102
|
+
#
|
103
|
+
# @return [String] The ID must contain only letters (a-z, A-Z), numbers
|
104
|
+
# (0-9), or underscores (_). The maximum length is 1,024 characters.
|
105
|
+
#
|
106
|
+
# @!group Attributes
|
107
|
+
#
|
108
|
+
def dataset_id
|
109
|
+
return @reference.dataset_id if reference?
|
110
|
+
@gapi_json[:modelReference][:datasetId]
|
111
|
+
end
|
112
|
+
|
113
|
+
##
|
114
|
+
# The ID of the `Project` containing this model.
|
115
|
+
#
|
116
|
+
# @return [String] The project ID.
|
117
|
+
#
|
118
|
+
# @!group Attributes
|
119
|
+
#
|
120
|
+
def project_id
|
121
|
+
return @reference.project_id if reference?
|
122
|
+
@gapi_json[:modelReference][:projectId]
|
123
|
+
end
|
124
|
+
|
125
|
+
##
|
126
|
+
# @private The gapi_json fragment containing the Project ID, Dataset ID,
|
127
|
+
# and Model ID.
|
128
|
+
#
|
129
|
+
# @return [Google::Apis::BigqueryV2::ModelReference]
|
130
|
+
#
|
131
|
+
def model_ref
|
132
|
+
return @reference if reference?
|
133
|
+
Google::Apis::BigqueryV2::ModelReference.new(
|
134
|
+
project_id: project_id,
|
135
|
+
dataset_id: dataset_id,
|
136
|
+
model_id: model_id
|
137
|
+
)
|
138
|
+
end
|
139
|
+
|
140
|
+
##
|
141
|
+
# Type of the model resource. Expected to be one of the following:
|
142
|
+
#
|
143
|
+
# * LINEAR_REGRESSION - Linear regression model.
|
144
|
+
# * LOGISTIC_REGRESSION - Logistic regression based classification
|
145
|
+
# model.
|
146
|
+
# * KMEANS - K-means clustering model (beta).
|
147
|
+
# * TENSORFLOW - An imported TensorFlow model (beta).
|
148
|
+
#
|
149
|
+
# @return [String, nil] The model type, or `nil` if the object is a
|
150
|
+
# reference (see {#reference?}).
|
151
|
+
#
|
152
|
+
# @!group Attributes
|
153
|
+
#
|
154
|
+
def model_type
|
155
|
+
return nil if reference?
|
156
|
+
@gapi_json[:modelType]
|
157
|
+
end
|
158
|
+
|
159
|
+
##
|
160
|
+
# The name of the model.
|
161
|
+
#
|
162
|
+
# @return [String, nil] The friendly name, or `nil` if the object is a
|
163
|
+
# reference (see {#reference?}).
|
164
|
+
#
|
165
|
+
# @!group Attributes
|
166
|
+
#
|
167
|
+
def name
|
168
|
+
return nil if reference?
|
169
|
+
ensure_full_data!
|
170
|
+
@gapi_json[:friendlyName]
|
171
|
+
end
|
172
|
+
|
173
|
+
##
|
174
|
+
# Updates the name of the model.
|
175
|
+
#
|
176
|
+
# If the model is not a full resource representation (see
|
177
|
+
# {#resource_full?}), the full representation will be retrieved before
|
178
|
+
# the update to comply with ETag-based optimistic concurrency control.
|
179
|
+
#
|
180
|
+
# @param [String] new_name The new friendly name.
|
181
|
+
#
|
182
|
+
# @!group Attributes
|
183
|
+
#
|
184
|
+
def name= new_name
|
185
|
+
ensure_full_data!
|
186
|
+
patch_gapi! friendlyName: new_name
|
187
|
+
end
|
188
|
+
|
189
|
+
##
|
190
|
+
# The ETag hash of the model.
|
191
|
+
#
|
192
|
+
# @return [String, nil] The ETag hash, or `nil` if the object is a
|
193
|
+
# reference (see {#reference?}).
|
194
|
+
#
|
195
|
+
# @!group Attributes
|
196
|
+
#
|
197
|
+
def etag
|
198
|
+
return nil if reference?
|
199
|
+
ensure_full_data!
|
200
|
+
@gapi_json[:etag]
|
201
|
+
end
|
202
|
+
|
203
|
+
##
|
204
|
+
# A user-friendly description of the model.
|
205
|
+
#
|
206
|
+
# @return [String, nil] The description, or `nil` if the object is a
|
207
|
+
# reference (see {#reference?}).
|
208
|
+
#
|
209
|
+
# @!group Attributes
|
210
|
+
#
|
211
|
+
def description
|
212
|
+
return nil if reference?
|
213
|
+
ensure_full_data!
|
214
|
+
@gapi_json[:description]
|
215
|
+
end
|
216
|
+
|
217
|
+
##
|
218
|
+
# Updates the user-friendly description of the model.
|
219
|
+
#
|
220
|
+
# If the model is not a full resource representation (see
|
221
|
+
# {#resource_full?}), the full representation will be retrieved before
|
222
|
+
# the update to comply with ETag-based optimistic concurrency control.
|
223
|
+
#
|
224
|
+
# @param [String] new_description The new user-friendly description.
|
225
|
+
#
|
226
|
+
# @!group Attributes
|
227
|
+
#
|
228
|
+
def description= new_description
|
229
|
+
ensure_full_data!
|
230
|
+
patch_gapi! description: new_description
|
231
|
+
end
|
232
|
+
|
233
|
+
##
|
234
|
+
# The time when this model was created.
|
235
|
+
#
|
236
|
+
# @return [Time, nil] The creation time, or `nil` if the object is a
|
237
|
+
# reference (see {#reference?}).
|
238
|
+
#
|
239
|
+
# @!group Attributes
|
240
|
+
#
|
241
|
+
def created_at
|
242
|
+
return nil if reference?
|
243
|
+
Convert.millis_to_time @gapi_json[:creationTime]
|
244
|
+
end
|
245
|
+
|
246
|
+
##
|
247
|
+
# The date when this model was last modified.
|
248
|
+
#
|
249
|
+
# @return [Time, nil] The last modified time, or `nil` if not present or
|
250
|
+
# the object is a reference (see {#reference?}).
|
251
|
+
#
|
252
|
+
# @!group Attributes
|
253
|
+
#
|
254
|
+
def modified_at
|
255
|
+
return nil if reference?
|
256
|
+
Convert.millis_to_time @gapi_json[:lastModifiedTime]
|
257
|
+
end
|
258
|
+
|
259
|
+
##
|
260
|
+
# The time when this model expires.
|
261
|
+
# If not present, the model will persist indefinitely.
|
262
|
+
# Expired models will be deleted and their storage reclaimed.
|
263
|
+
#
|
264
|
+
# @return [Time, nil] The expiration time, or `nil` if not present or
|
265
|
+
# the object is a reference (see {#reference?}).
|
266
|
+
#
|
267
|
+
# @!group Attributes
|
268
|
+
#
|
269
|
+
def expires_at
|
270
|
+
return nil if reference?
|
271
|
+
ensure_full_data!
|
272
|
+
Convert.millis_to_time @gapi_json[:expirationTime]
|
273
|
+
end
|
274
|
+
|
275
|
+
##
|
276
|
+
# Updates time when this model expires.
|
277
|
+
#
|
278
|
+
# If the model is not a full resource representation (see
|
279
|
+
# {#resource_full?}), the full representation will be retrieved before
|
280
|
+
# the update to comply with ETag-based optimistic concurrency control.
|
281
|
+
#
|
282
|
+
# @param [Integer] new_expires_at The new time when this model expires.
|
283
|
+
#
|
284
|
+
# @!group Attributes
|
285
|
+
#
|
286
|
+
def expires_at= new_expires_at
|
287
|
+
ensure_full_data!
|
288
|
+
new_expires_millis = Convert.time_to_millis new_expires_at
|
289
|
+
patch_gapi! expirationTime: new_expires_millis
|
290
|
+
end
|
291
|
+
|
292
|
+
##
|
293
|
+
# The geographic location where the model should reside. Possible
|
294
|
+
# values include `EU` and `US`. The default value is `US`.
|
295
|
+
#
|
296
|
+
# @return [String, nil] The location code.
|
297
|
+
#
|
298
|
+
# @!group Attributes
|
299
|
+
#
|
300
|
+
def location
|
301
|
+
return nil if reference?
|
302
|
+
ensure_full_data!
|
303
|
+
@gapi_json[:location]
|
304
|
+
end
|
305
|
+
|
306
|
+
##
|
307
|
+
# A hash of user-provided labels associated with this model. Labels
|
308
|
+
# are used to organize and group models. See [Using
|
309
|
+
# Labels](https://cloud.google.com/bigquery/docs/labels).
|
310
|
+
#
|
311
|
+
# The returned hash is frozen and changes are not allowed. Use
|
312
|
+
# {#labels=} to replace the entire hash.
|
313
|
+
#
|
314
|
+
# @return [Hash<String, String>, nil] A hash containing key/value pairs.
|
315
|
+
#
|
316
|
+
# @example
|
317
|
+
# require "google/cloud/bigquery"
|
318
|
+
#
|
319
|
+
# bigquery = Google::Cloud::Bigquery.new
|
320
|
+
# dataset = bigquery.dataset "my_dataset"
|
321
|
+
# model = dataset.model "my_model"
|
322
|
+
#
|
323
|
+
# labels = model.labels
|
324
|
+
#
|
325
|
+
# @!group Attributes
|
326
|
+
#
|
327
|
+
def labels
|
328
|
+
return nil if reference?
|
329
|
+
m = @gapi_json[:labels]
|
330
|
+
m = m.to_h if m.respond_to? :to_h
|
331
|
+
m.dup.freeze
|
332
|
+
end
|
333
|
+
|
334
|
+
##
|
335
|
+
# Updates the hash of user-provided labels associated with this model.
|
336
|
+
# Labels are used to organize and group models. See [Using
|
337
|
+
# Labels](https://cloud.google.com/bigquery/docs/labels).
|
338
|
+
#
|
339
|
+
# If the model is not a full resource representation (see
|
340
|
+
# {#resource_full?}), the full representation will be retrieved before
|
341
|
+
# the update to comply with ETag-based optimistic concurrency control.
|
342
|
+
#
|
343
|
+
# @param [Hash<String, String>] new_labels A hash containing key/value
|
344
|
+
# pairs.
|
345
|
+
#
|
346
|
+
# * Label keys and values can be no longer than 63 characters.
|
347
|
+
# * Label keys and values can contain only lowercase letters, numbers,
|
348
|
+
# underscores, hyphens, and international characters.
|
349
|
+
# * Label keys and values cannot exceed 128 bytes in size.
|
350
|
+
# * Label keys must begin with a letter.
|
351
|
+
# * Label keys must be unique within a model.
|
352
|
+
#
|
353
|
+
# @example
|
354
|
+
# require "google/cloud/bigquery"
|
355
|
+
#
|
356
|
+
# bigquery = Google::Cloud::Bigquery.new
|
357
|
+
# dataset = bigquery.dataset "my_dataset"
|
358
|
+
# model = dataset.model "my_model"
|
359
|
+
#
|
360
|
+
# model.labels = { "env" => "production" }
|
361
|
+
#
|
362
|
+
# @!group Attributes
|
363
|
+
#
|
364
|
+
def labels= new_labels
|
365
|
+
ensure_full_data!
|
366
|
+
patch_gapi! labels: new_labels
|
367
|
+
end
|
368
|
+
|
369
|
+
##
|
370
|
+
# The {EncryptionConfiguration} object that represents the custom
|
371
|
+
# encryption method used to protect this model. If not set,
|
372
|
+
# {Dataset#default_encryption} is used.
|
373
|
+
#
|
374
|
+
# Present only if this model is using custom encryption.
|
375
|
+
#
|
376
|
+
# @see https://cloud.google.com/bigquery/docs/customer-managed-encryption
|
377
|
+
# Protecting Data with Cloud KMS Keys
|
378
|
+
#
|
379
|
+
# @return [EncryptionConfiguration, nil] The encryption configuration.
|
380
|
+
#
|
381
|
+
# @!group Attributes
|
382
|
+
#
|
383
|
+
# @example
|
384
|
+
# require "google/cloud/bigquery"
|
385
|
+
#
|
386
|
+
# bigquery = Google::Cloud::Bigquery.new
|
387
|
+
# dataset = bigquery.dataset "my_dataset"
|
388
|
+
# model = dataset.model "my_model"
|
389
|
+
#
|
390
|
+
# encrypt_config = model.encryption
|
391
|
+
#
|
392
|
+
# @!group Attributes
|
393
|
+
#
|
394
|
+
def encryption
|
395
|
+
return nil if reference?
|
396
|
+
return nil if @gapi_json[:encryptionConfiguration].nil?
|
397
|
+
# We have to create a gapic object from the hash because that is what
|
398
|
+
# EncryptionConfiguration is expecing.
|
399
|
+
json_cmek = @gapi_json[:encryptionConfiguration].to_json
|
400
|
+
gapi_cmek = Google::Apis::BigqueryV2::EncryptionConfiguration.from_json json_cmek
|
401
|
+
EncryptionConfiguration.from_gapi(gapi_cmek).freeze
|
402
|
+
end
|
403
|
+
|
404
|
+
##
|
405
|
+
# Set the {EncryptionConfiguration} object that represents the custom
|
406
|
+
# encryption method used to protect this model. If not set,
|
407
|
+
# {Dataset#default_encryption} is used.
|
408
|
+
#
|
409
|
+
# Present only if this model is using custom encryption.
|
410
|
+
#
|
411
|
+
# If the model is not a full resource representation (see
|
412
|
+
# {#resource_full?}), the full representation will be retrieved before
|
413
|
+
# the update to comply with ETag-based optimistic concurrency control.
|
414
|
+
#
|
415
|
+
# @see https://cloud.google.com/bigquery/docs/customer-managed-encryption
|
416
|
+
# Protecting Data with Cloud KMS Keys
|
417
|
+
#
|
418
|
+
# @param [EncryptionConfiguration] value The new encryption config.
|
419
|
+
#
|
420
|
+
# @example
|
421
|
+
# require "google/cloud/bigquery"
|
422
|
+
#
|
423
|
+
# bigquery = Google::Cloud::Bigquery.new
|
424
|
+
# dataset = bigquery.dataset "my_dataset"
|
425
|
+
# model = dataset.model "my_model"
|
426
|
+
#
|
427
|
+
# key_name = "projects/a/locations/b/keyRings/c/cryptoKeys/d"
|
428
|
+
# encrypt_config = bigquery.encryption kms_key: key_name
|
429
|
+
#
|
430
|
+
# model.encryption = encrypt_config
|
431
|
+
#
|
432
|
+
# @!group Attributes
|
433
|
+
#
|
434
|
+
def encryption= value
|
435
|
+
ensure_full_data!
|
436
|
+
# We have to create a hash from the gapic object's JSON because that
|
437
|
+
# is what Model is expecing.
|
438
|
+
json_cmek = JSON.parse value.to_gapi.to_json, symbolize_names: true
|
439
|
+
patch_gapi! encryptionConfiguration: json_cmek
|
440
|
+
end
|
441
|
+
|
442
|
+
##
|
443
|
+
# The input feature columns that were used to train this model.
|
444
|
+
#
|
445
|
+
# @return [Array<StandardSql::Field>]
|
446
|
+
#
|
447
|
+
# @!group Attributes
|
448
|
+
#
|
449
|
+
def feature_columns
|
450
|
+
ensure_full_data!
|
451
|
+
Array(@gapi_json[:featureColumns]).map do |field_gapi_json|
|
452
|
+
field_gapi = Google::Apis::BigqueryV2::StandardSqlField.from_json field_gapi_json.to_json
|
453
|
+
StandardSql::Field.from_gapi field_gapi
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
##
|
458
|
+
# The label columns that were used to train this model. The output of
|
459
|
+
# the model will have a "predicted_" prefix to these columns.
|
460
|
+
#
|
461
|
+
# @return [Array<StandardSql::Field>]
|
462
|
+
#
|
463
|
+
# @!group Attributes
|
464
|
+
#
|
465
|
+
def label_columns
|
466
|
+
ensure_full_data!
|
467
|
+
Array(@gapi_json[:labelColumns]).map do |field_gapi_json|
|
468
|
+
field_gapi = Google::Apis::BigqueryV2::StandardSqlField.from_json field_gapi_json.to_json
|
469
|
+
StandardSql::Field.from_gapi field_gapi
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
##
|
474
|
+
# Information for all training runs in increasing order of startTime.
|
475
|
+
#
|
476
|
+
# @return [Array<Google::Cloud::Bigquery::Model::TrainingRun>]
|
477
|
+
#
|
478
|
+
# @!group Attributes
|
479
|
+
#
|
480
|
+
def training_runs
|
481
|
+
ensure_full_data!
|
482
|
+
Array @gapi_json[:trainingRuns]
|
483
|
+
end
|
484
|
+
|
485
|
+
##
|
486
|
+
# Permanently deletes the model.
|
487
|
+
#
|
488
|
+
# @return [Boolean] Returns `true` if the model was deleted.
|
489
|
+
#
|
490
|
+
# @example
|
491
|
+
# require "google/cloud/bigquery"
|
492
|
+
#
|
493
|
+
# bigquery = Google::Cloud::Bigquery.new
|
494
|
+
# dataset = bigquery.dataset "my_dataset"
|
495
|
+
# model = dataset.model "my_model"
|
496
|
+
#
|
497
|
+
# model.delete
|
498
|
+
#
|
499
|
+
# @!group Lifecycle
|
500
|
+
#
|
501
|
+
def delete
|
502
|
+
ensure_service!
|
503
|
+
service.delete_model dataset_id, model_id
|
504
|
+
# Set flag for #exists?
|
505
|
+
@exists = false
|
506
|
+
true
|
507
|
+
end
|
508
|
+
|
509
|
+
##
|
510
|
+
# Reloads the model with current data from the BigQuery service.
|
511
|
+
#
|
512
|
+
# @return [Google::Cloud::Bigquery::Model] Returns the reloaded
|
513
|
+
# model.
|
514
|
+
#
|
515
|
+
# @example Skip retrieving the model from the service, then load it:
|
516
|
+
# require "google/cloud/bigquery"
|
517
|
+
#
|
518
|
+
# bigquery = Google::Cloud::Bigquery.new
|
519
|
+
#
|
520
|
+
# dataset = bigquery.dataset "my_dataset"
|
521
|
+
# model = dataset.model "my_model", skip_lookup: true
|
522
|
+
#
|
523
|
+
# model.reference? #=> true
|
524
|
+
# model.reload!
|
525
|
+
# model.resource? #=> true
|
526
|
+
#
|
527
|
+
# @!group Lifecycle
|
528
|
+
#
|
529
|
+
def reload!
|
530
|
+
ensure_service!
|
531
|
+
@gapi_json = service.get_model dataset_id, model_id
|
532
|
+
@reference = nil
|
533
|
+
@exists = nil
|
534
|
+
self
|
535
|
+
end
|
536
|
+
alias refresh! reload!
|
537
|
+
|
538
|
+
##
|
539
|
+
# Determines whether the model exists in the BigQuery service. The
|
540
|
+
# result is cached locally. To refresh state, set `force` to `true`.
|
541
|
+
#
|
542
|
+
# @param [Boolean] force Force the latest resource representation to be
|
543
|
+
# retrieved from the BigQuery service when `true`. Otherwise the
|
544
|
+
# return value of this method will be memoized to reduce the number of
|
545
|
+
# API calls made to the BigQuery service. The default is `false`.
|
546
|
+
#
|
547
|
+
# @return [Boolean] `true` when the model exists in the BigQuery
|
548
|
+
# service, `false` otherwise.
|
549
|
+
#
|
550
|
+
# @example
|
551
|
+
# require "google/cloud/bigquery"
|
552
|
+
#
|
553
|
+
# bigquery = Google::Cloud::Bigquery.new
|
554
|
+
#
|
555
|
+
# dataset = bigquery.dataset "my_dataset"
|
556
|
+
# model = dataset.model "my_model", skip_lookup: true
|
557
|
+
# model.exists? #=> true
|
558
|
+
#
|
559
|
+
def exists? force: false
|
560
|
+
return resource_exists? if force
|
561
|
+
# If we have a value, return it
|
562
|
+
return @exists unless @exists.nil?
|
563
|
+
# Always true if we have a gapi_json object
|
564
|
+
return true if resource?
|
565
|
+
resource_exists?
|
566
|
+
end
|
567
|
+
|
568
|
+
##
|
569
|
+
# Whether the model was created without retrieving the resource
|
570
|
+
# representation from the BigQuery service.
|
571
|
+
#
|
572
|
+
# @return [Boolean] `true` when the model is just a local reference
|
573
|
+
# object, `false` otherwise.
|
574
|
+
#
|
575
|
+
# @example
|
576
|
+
# require "google/cloud/bigquery"
|
577
|
+
#
|
578
|
+
# bigquery = Google::Cloud::Bigquery.new
|
579
|
+
#
|
580
|
+
# dataset = bigquery.dataset "my_dataset"
|
581
|
+
# model = dataset.model "my_model", skip_lookup: true
|
582
|
+
#
|
583
|
+
# model.reference? #=> true
|
584
|
+
# model.reload!
|
585
|
+
# model.reference? #=> false
|
586
|
+
#
|
587
|
+
def reference?
|
588
|
+
@gapi_json.nil?
|
589
|
+
end
|
590
|
+
|
591
|
+
##
|
592
|
+
# Whether the model was created with a resource representation from
|
593
|
+
# the BigQuery service.
|
594
|
+
#
|
595
|
+
# @return [Boolean] `true` when the model was created with a resource
|
596
|
+
# representation, `false` otherwise.
|
597
|
+
#
|
598
|
+
# @example
|
599
|
+
# require "google/cloud/bigquery"
|
600
|
+
#
|
601
|
+
# bigquery = Google::Cloud::Bigquery.new
|
602
|
+
#
|
603
|
+
# dataset = bigquery.dataset "my_dataset"
|
604
|
+
# model = dataset.model "my_model", skip_lookup: true
|
605
|
+
#
|
606
|
+
# model.resource? #=> false
|
607
|
+
# model.reload!
|
608
|
+
# model.resource? #=> true
|
609
|
+
#
|
610
|
+
def resource?
|
611
|
+
!@gapi_json.nil?
|
612
|
+
end
|
613
|
+
|
614
|
+
##
|
615
|
+
# Whether the model was created with a partial resource representation
|
616
|
+
# from the BigQuery service by retrieval through {Dataset#models}.
|
617
|
+
# See [Models: list
|
618
|
+
# response](https://cloud.google.com/bigquery/docs/reference/rest/v2/models/list#response)
|
619
|
+
# for the contents of the partial representation. Accessing any
|
620
|
+
# attribute outside of the partial representation will result in loading
|
621
|
+
# the full representation.
|
622
|
+
#
|
623
|
+
# @return [Boolean] `true` when the model was created with a partial
|
624
|
+
# resource representation, `false` otherwise.
|
625
|
+
#
|
626
|
+
# @example
|
627
|
+
# require "google/cloud/bigquery"
|
628
|
+
#
|
629
|
+
# bigquery = Google::Cloud::Bigquery.new
|
630
|
+
#
|
631
|
+
# dataset = bigquery.dataset "my_dataset"
|
632
|
+
# model = dataset.models.first
|
633
|
+
#
|
634
|
+
# model.resource_partial? #=> true
|
635
|
+
# model.description # Loads the full resource.
|
636
|
+
# model.resource_partial? #=> false
|
637
|
+
#
|
638
|
+
def resource_partial?
|
639
|
+
resource? && !resource_full?
|
640
|
+
end
|
641
|
+
|
642
|
+
##
|
643
|
+
# Whether the model was created with a full resource representation
|
644
|
+
# from the BigQuery service.
|
645
|
+
#
|
646
|
+
# @return [Boolean] `true` when the model was created with a full
|
647
|
+
# resource representation, `false` otherwise.
|
648
|
+
#
|
649
|
+
# @example
|
650
|
+
# require "google/cloud/bigquery"
|
651
|
+
#
|
652
|
+
# bigquery = Google::Cloud::Bigquery.new
|
653
|
+
#
|
654
|
+
# dataset = bigquery.dataset "my_dataset"
|
655
|
+
# model = dataset.model "my_model"
|
656
|
+
#
|
657
|
+
# model.resource_full? #=> true
|
658
|
+
#
|
659
|
+
def resource_full?
|
660
|
+
resource? && @gapi_json.key?(:friendlyName)
|
661
|
+
end
|
662
|
+
|
663
|
+
##
|
664
|
+
# @private New Model from a Google API Client object.
|
665
|
+
def self.from_gapi_json gapi_json, service
|
666
|
+
new.tap do |m|
|
667
|
+
m.instance_variable_set :@gapi_json, gapi_json
|
668
|
+
m.instance_variable_set :@service, service
|
669
|
+
end
|
670
|
+
end
|
671
|
+
|
672
|
+
##
|
673
|
+
# @private New lazy Model object without making an HTTP request, for use with the skip_lookup option.
|
674
|
+
def self.new_reference project_id, dataset_id, model_id, service
|
675
|
+
raise ArgumentError, "project_id is required" unless project_id
|
676
|
+
raise ArgumentError, "dataset_id is required" unless dataset_id
|
677
|
+
raise ArgumentError, "model_id is required" unless model_id
|
678
|
+
raise ArgumentError, "service is required" unless service
|
679
|
+
|
680
|
+
new.tap do |m|
|
681
|
+
reference_gapi_json = Google::Apis::BigqueryV2::ModelReference.new(
|
682
|
+
project_id: project_id,
|
683
|
+
dataset_id: dataset_id,
|
684
|
+
model_id: model_id
|
685
|
+
)
|
686
|
+
m.instance_variable_set :@reference, reference_gapi_json
|
687
|
+
m.instance_variable_set :@service, service
|
688
|
+
end
|
689
|
+
end
|
690
|
+
|
691
|
+
protected
|
692
|
+
|
693
|
+
##
|
694
|
+
# Raise an error unless an active service is available.
|
695
|
+
def ensure_service!
|
696
|
+
raise "Must have active connection" unless service
|
697
|
+
end
|
698
|
+
|
699
|
+
##
|
700
|
+
# Ensures the Google::Apis::BigqueryV2::Model object has been loaded
|
701
|
+
# from the service.
|
702
|
+
def ensure_gapi_json!
|
703
|
+
ensure_service!
|
704
|
+
return unless reference?
|
705
|
+
reload!
|
706
|
+
end
|
707
|
+
|
708
|
+
##
|
709
|
+
# Fetch gapi_json and memoize whether resource exists.
|
710
|
+
def resource_exists?
|
711
|
+
reload!
|
712
|
+
@exists = true
|
713
|
+
rescue Google::Cloud::NotFoundError
|
714
|
+
@exists = false
|
715
|
+
end
|
716
|
+
|
717
|
+
def patch_gapi! **changes
|
718
|
+
return if changes.empty?
|
719
|
+
ensure_service!
|
720
|
+
patch_gapi = Google::Apis::BigqueryV2::Model.from_json changes.to_json
|
721
|
+
patch_gapi.model_reference = model_ref
|
722
|
+
@gapi_json = service.patch_model \
|
723
|
+
dataset_id, model_id, patch_gapi, etag
|
724
|
+
@reference = nil
|
725
|
+
|
726
|
+
# TODO: restore original impl after acceptance test indicates that
|
727
|
+
# service etag bug is fixed
|
728
|
+
reload!
|
729
|
+
end
|
730
|
+
|
731
|
+
##
|
732
|
+
# Load the complete representation of the model if it has been
|
733
|
+
# only partially loaded by a request to the API list method.
|
734
|
+
def ensure_full_data!
|
735
|
+
reload! unless resource_full?
|
736
|
+
end
|
737
|
+
end
|
738
|
+
end
|
739
|
+
end
|
740
|
+
end
|