def download(self, *query, **kwargs): """download(*query, client=sunpy.net.vso.VSOClient(), path=None, progress=False) Search for data using the VSO interface (see :meth:`sunpy.net.vso.VSOClient.query`). If querying the VSO results in no data, no operation is performed. Concrete, this means that no entry is added to the database and no file is downloaded. Otherwise, the retrieved search result is used to download all files that belong to this search result. After that, all the gathered information (the one from the VSO query result and the one from the downloaded FITS files) is added to the database in a way that each FITS header is represented by one database entry. """ if not query: raise TypeError('at least one attribute required') client = kwargs.pop('client', None) path = kwargs.pop('path', None) progress = kwargs.pop('progress', False) if kwargs: k, v = kwargs.popitem() raise TypeError('unexpected keyword argument {0!r}'.format(k)) if client is None: client = VSOClient() qr = client.query(*query) # don't do anything if querying the VSO results in no data if not qr: return entries = list( self._download_and_collect_entries(qr, client, path, progress)) dump = serialize.dump_query(and_(*query)) (dump_exists, ), = self.session.query( exists().where(tables.JSONDump.dump == tables.JSONDump(dump).dump)) if dump_exists: # dump already exists in table jsondumps -> edit instead of add # update all entries with the fileid `entry.fileid` for entry in entries: old_entry = self.session.query(tables.DatabaseEntry).filter_by( fileid=entry.fileid).first() if old_entry is not None: attrs = [ 'source', 'provider', 'physobs', 'observation_time_start', 'observation_time_end', 'instrument', 'size', 'wavemin', 'wavemax', 'download_time' ] kwargs = dict((k, getattr(entry, k)) for k in attrs) cmd = commands.EditEntry(old_entry, **kwargs) if self._enable_history: self._command_manager.do(cmd) else: cmd() else: self.add_many(entries) # serialize the query and save the serialization in the database # for two reasons: # 1. to avoid unnecessary downloading in future calls of # ``fetch`` # 2. to know whether to add or to edit entries in future calls of # ``download`` (this method) self.session.add(tables.JSONDump(dump))
def fetch(self, *query, **kwargs): """fetch(*query[, path]) Check if the query has already been used to collect new data using the :meth:`sunpy.database.Database.download` method. If yes, query the database using the method :meth:`sunpy.database.Database.query` and return the result. Otherwise, call :meth:`sunpy.database.Database.download` and return the result. """ if not query: raise TypeError('at least one attribute required') dump = serialize.dump_query(and_(*query)) (dump_exists, ), = self.session.query( exists().where(tables.JSONDump.dump == tables.JSONDump(dump).dump)) if dump_exists: return self.query(*query) return self.download(*query, **kwargs)