@@ -227,6 +227,112 @@ def state(self):
227227 if status is not None :
228228 return status .get ('state' )
229229
230+ def _require_client (self , client ):
231+ """Check client or verify over-ride.
232+
233+ :type client: :class:`gcloud.bigquery.client.Client` or ``NoneType``
234+ :param client: the client to use. If not passed, falls back to the
235+ ``client`` stored on the current dataset.
236+
237+ :rtype: :class:`gcloud.bigquery.client.Client`
238+ :returns: The client passed in or the currently bound client.
239+ """
240+ if client is None :
241+ client = self ._client
242+ return client
243+
244+ def _scrub_local_properties (self , cleaned ):
245+ """Helper: handle subclass properties in cleaned."""
246+ pass
247+
248+ def _set_properties (self , api_response ):
249+ """Update properties from resource in body of ``api_response``
250+
251+ :type api_response: httplib2.Response
252+ :param api_response: response returned from an API call
253+ """
254+ cleaned = api_response .copy ()
255+ self ._scrub_local_properties (cleaned )
256+
257+ statistics = cleaned .get ('statistics' , {})
258+ if 'creationTime' in statistics :
259+ statistics ['creationTime' ] = float (statistics ['creationTime' ])
260+ if 'startTime' in statistics :
261+ statistics ['startTime' ] = float (statistics ['startTime' ])
262+ if 'endTime' in statistics :
263+ statistics ['endTime' ] = float (statistics ['endTime' ])
264+
265+ self ._properties .clear ()
266+ self ._properties .update (cleaned )
267+
268+ def begin (self , client = None ):
269+ """API call: begin the job via a POST request
270+
271+ See:
272+ https://cloud.google.com/bigquery/docs/reference/v2/jobs/insert
273+
274+ :type client: :class:`gcloud.bigquery.client.Client` or ``NoneType``
275+ :param client: the client to use. If not passed, falls back to the
276+ ``client`` stored on the current dataset.
277+ """
278+ client = self ._require_client (client )
279+ path = '/projects/%s/jobs' % (self .project ,)
280+ api_response = client .connection .api_request (
281+ method = 'POST' , path = path , data = self ._build_resource ())
282+ self ._set_properties (api_response )
283+
284+ def exists (self , client = None ):
285+ """API call: test for the existence of the job via a GET request
286+
287+ See
288+ https://cloud.google.com/bigquery/docs/reference/v2/jobs/get
289+
290+ :type client: :class:`gcloud.bigquery.client.Client` or ``NoneType``
291+ :param client: the client to use. If not passed, falls back to the
292+ ``client`` stored on the current dataset.
293+ """
294+ client = self ._require_client (client )
295+
296+ try :
297+ client .connection .api_request (method = 'GET' , path = self .path ,
298+ query_params = {'fields' : 'id' })
299+ except NotFound :
300+ return False
301+ else :
302+ return True
303+
304+ def reload (self , client = None ):
305+ """API call: refresh job properties via a GET request
306+
307+ See
308+ https://cloud.google.com/bigquery/docs/reference/v2/jobs/get
309+
310+ :type client: :class:`gcloud.bigquery.client.Client` or ``NoneType``
311+ :param client: the client to use. If not passed, falls back to the
312+ ``client`` stored on the current dataset.
313+ """
314+ client = self ._require_client (client )
315+
316+ api_response = client .connection .api_request (
317+ method = 'GET' , path = self .path )
318+ self ._set_properties (api_response )
319+
320+ def cancel (self , client = None ):
321+ """API call: cancel job via a POST request
322+
323+ See
324+ https://cloud.google.com/bigquery/docs/reference/v2/jobs/cancel
325+
326+ :type client: :class:`gcloud.bigquery.client.Client` or ``NoneType``
327+ :param client: the client to use. If not passed, falls back to the
328+ ``client`` stored on the current dataset.
329+ """
330+ client = self ._require_client (client )
331+
332+ api_response = client .connection .api_request (
333+ method = 'POST' , path = '%s/cancel' % self .path )
334+ self ._set_properties (api_response )
335+
230336
231337class _LoadConfiguration (object ):
232338 """User-settable configuration options for load jobs."""
@@ -622,20 +728,6 @@ def write_disposition(self):
622728 """Delete write_disposition."""
623729 del self ._configuration ._write_disposition
624730
625- def _require_client (self , client ):
626- """Check client or verify over-ride.
627-
628- :type client: :class:`gcloud.bigquery.client.Client` or ``NoneType``
629- :param client: the client to use. If not passed, falls back to the
630- ``client`` stored on the current dataset.
631-
632- :rtype: :class:`gcloud.bigquery.client.Client`
633- :returns: The client passed in or the currently bound client.
634- """
635- if client is None :
636- client = self ._client
637- return client
638-
639731 def _populate_config_resource (self , configuration ):
640732 """Helper for _build_resource: copy config properties to resource"""
641733 if self .allow_jagged_rows is not None :
@@ -688,95 +780,11 @@ def _build_resource(self):
688780
689781 return resource
690782
691- def _set_properties (self , api_response ):
692- """Update properties from resource in body of ``api_response``
693-
694- :type api_response: httplib2.Response
695- :param api_response: response returned from an API call
696- """
697- self ._properties .clear ()
698- cleaned = api_response .copy ()
783+ def _scrub_local_properties (self , cleaned ):
784+ """Helper: handle subclass properties in cleaned."""
699785 schema = cleaned .pop ('schema' , {'fields' : ()})
700786 self .schema = _parse_schema_resource (schema )
701787
702- statistics = cleaned .get ('statistics' , {})
703- if 'creationTime' in statistics :
704- statistics ['creationTime' ] = float (statistics ['creationTime' ])
705- if 'startTime' in statistics :
706- statistics ['startTime' ] = float (statistics ['startTime' ])
707- if 'endTime' in statistics :
708- statistics ['endTime' ] = float (statistics ['endTime' ])
709-
710- self ._properties .update (cleaned )
711-
712- def begin (self , client = None ):
713- """API call: begin the job via a POST request
714-
715- See:
716- https://cloud.google.com/bigquery/docs/reference/v2/jobs/insert
717-
718- :type client: :class:`gcloud.bigquery.client.Client` or ``NoneType``
719- :param client: the client to use. If not passed, falls back to the
720- ``client`` stored on the current dataset.
721- """
722- client = self ._require_client (client )
723- path = '/projects/%s/jobs' % (self .project ,)
724- api_response = client .connection .api_request (
725- method = 'POST' , path = path , data = self ._build_resource ())
726- self ._set_properties (api_response )
727-
728- def exists (self , client = None ):
729- """API call: test for the existence of the job via a GET request
730-
731- See
732- https://cloud.google.com/bigquery/docs/reference/v2/jobs/get
733-
734- :type client: :class:`gcloud.bigquery.client.Client` or ``NoneType``
735- :param client: the client to use. If not passed, falls back to the
736- ``client`` stored on the current dataset.
737- """
738- client = self ._require_client (client )
739-
740- try :
741- client .connection .api_request (method = 'GET' , path = self .path ,
742- query_params = {'fields' : 'id' })
743- except NotFound :
744- return False
745- else :
746- return True
747-
748- def reload (self , client = None ):
749- """API call: refresh job properties via a GET request
750-
751- See
752- https://cloud.google.com/bigquery/docs/reference/v2/jobs/get
753-
754- :type client: :class:`gcloud.bigquery.client.Client` or ``NoneType``
755- :param client: the client to use. If not passed, falls back to the
756- ``client`` stored on the current dataset.
757- """
758- client = self ._require_client (client )
759-
760- api_response = client .connection .api_request (
761- method = 'GET' , path = self .path )
762- self ._set_properties (api_response )
763-
764- def cancel (self , client = None ):
765- """API call: cancel job via a POST request
766-
767- See
768- https://cloud.google.com/bigquery/docs/reference/v2/jobs/cancel
769-
770- :type client: :class:`gcloud.bigquery.client.Client` or ``NoneType``
771- :param client: the client to use. If not passed, falls back to the
772- ``client`` stored on the current dataset.
773- """
774- client = self ._require_client (client )
775-
776- api_response = client .connection .api_request (
777- method = 'POST' , path = '%s/cancel' % self .path )
778- self ._set_properties (api_response )
779-
780788
781789class _CopyConfiguration (object ):
782790 """User-settable configuration options for copy jobs."""
@@ -855,3 +863,40 @@ def write_disposition(self, value):
855863 def write_disposition (self ):
856864 """Delete write_disposition."""
857865 del self ._configuration ._write_disposition
866+
867+ def _populate_config_resource (self , configuration ):
868+
869+ if self .create_disposition is not None :
870+ configuration ['createDisposition' ] = self .create_disposition
871+ if self .write_disposition is not None :
872+ configuration ['writeDisposition' ] = self .write_disposition
873+
874+ def _build_resource (self ):
875+ """Generate a resource for ``begin``."""
876+
877+ source_refs = [{
878+ 'projectId' : table .project ,
879+ 'datasetId' : table .dataset_name ,
880+ 'tableId' : table .name ,
881+ } for table in self .sources ]
882+
883+ resource = {
884+ 'jobReference' : {
885+ 'projectId' : self .project ,
886+ 'jobId' : self .name ,
887+ },
888+ 'configuration' : {
889+ 'copy' : {
890+ 'sourceTables' : source_refs ,
891+ 'destinationTable' : {
892+ 'projectId' : self .destination .project ,
893+ 'datasetId' : self .destination .dataset_name ,
894+ 'tableId' : self .destination .name ,
895+ },
896+ },
897+ },
898+ }
899+ configuration = resource ['configuration' ]['copy' ]
900+ self ._populate_config_resource (configuration )
901+
902+ return resource
0 commit comments