@@ -149,26 +149,30 @@ def __call__(self, *attrs, offset=None, limit=None, order_by=None, format=None,
149
149
attrs = list (self ._expression .primary_key ) + [
150
150
a for a in attrs if a not in self ._expression .primary_key ]
151
151
if as_dict is None :
152
- as_dict = bool (attrs ) # default to True for "KEY" and False when fetching entire result
152
+ as_dict = bool (attrs ) # default to True for "KEY" and False otherwise
153
153
# format should not be specified with attrs or is_dict=True
154
154
if format is not None and (as_dict or attrs ):
155
155
raise DataJointError ('Cannot specify output format when as_dict=True or '
156
156
'when attributes are selected to be fetched separately.' )
157
157
if format not in {None , "array" , "frame" }:
158
- raise DataJointError ('Fetch output format must be in {{"array", "frame"}} but "{}" was given' .format (format ))
158
+ raise DataJointError (
159
+ 'Fetch output format must be in '
160
+ '{{"array", "frame"}} but "{}" was given' .format (format ))
159
161
160
162
if not (attrs or as_dict ) and format is None :
161
163
format = config ['fetch_format' ] # default to array
162
164
if format not in {"array" , "frame" }:
163
- raise DataJointError ('Invalid entry "{}" in datajoint.config["fetch_format"]: use "array" or "frame"' .format (
164
- format ))
165
+ raise DataJointError (
166
+ 'Invalid entry "{}" in datajoint.config["fetch_format"]: '
167
+ 'use "array" or "frame"' .format (format ))
165
168
166
169
if limit is None and offset is not None :
167
170
warnings .warn ('Offset set, but no limit. Setting limit to a large number. '
168
171
'Consider setting a limit explicitly.' )
169
172
limit = 8000000000 # just a very large number to effect no limit
170
173
171
- get = partial (_get , self ._expression .connection , squeeze = squeeze , download_path = download_path )
174
+ get = partial (_get , self ._expression .connection ,
175
+ squeeze = squeeze , download_path = download_path )
172
176
if attrs : # a list of attributes provided
173
177
attributes = [a for a in attrs if not is_key (a )]
174
178
ret = self ._expression .proj (* attributes )
@@ -179,19 +183,22 @@ def __call__(self, *attrs, offset=None, limit=None, order_by=None, format=None,
179
183
if attrs_as_dict :
180
184
ret = [{k : v for k , v in zip (ret .dtype .names , x ) if k in attrs } for x in ret ]
181
185
else :
182
- return_values = [
183
- list ((to_dicts if as_dict else lambda x : x )(ret [self ._expression .primary_key ])) if is_key (attribute )
184
- else ret [attribute ] for attribute in attrs ]
186
+ return_values = [list (
187
+ (to_dicts if as_dict else lambda x : x )(ret [self ._expression .primary_key ]))
188
+ if is_key (attribute ) else ret [attribute ]
189
+ for attribute in attrs ]
185
190
ret = return_values [0 ] if len (attrs ) == 1 else return_values
186
191
else : # fetch all attributes as a numpy.record_array or pandas.DataFrame
187
- cur = self ._expression .cursor (as_dict = as_dict , limit = limit , offset = offset , order_by = order_by )
192
+ cur = self ._expression .cursor (
193
+ as_dict = as_dict , limit = limit , offset = offset , order_by = order_by )
188
194
heading = self ._expression .heading
189
195
if as_dict :
190
- ret = [dict ((name , get (heading [name ], d [name ])) for name in heading .names ) for d in cur ]
196
+ ret = [dict ((name , get (heading [name ], d [name ]))
197
+ for name in heading .names ) for d in cur ]
191
198
else :
192
199
ret = list (cur .fetchall ())
193
200
record_type = (heading .as_dtype if not ret else np .dtype (
194
- [(name , type (value )) # use the first element to determine the type for blobs
201
+ [(name , type (value )) # use the first element to determine blob type
195
202
if heading [name ].is_blob and isinstance (value , numbers .Number )
196
203
else (name , heading .as_dtype [name ])
197
204
for value , name in zip (ret [0 ], heading .as_dtype .names )]))
@@ -208,15 +215,15 @@ def __call__(self, *attrs, offset=None, limit=None, order_by=None, format=None,
208
215
209
216
class Fetch1 :
210
217
"""
211
- Fetch object for fetching exactly one row.
212
- :param relation: relation the fetch object fetches data from
218
+ Fetch object for fetching the result of a query yielding one row.
219
+ :param expression: a query expression to fetch from.
213
220
"""
214
- def __init__ (self , relation ):
215
- self ._expression = relation
221
+ def __init__ (self , expression ):
222
+ self ._expression = expression
216
223
217
224
def __call__ (self , * attrs , squeeze = False , download_path = '.' ):
218
225
"""
219
- Fetches the expression results from the database when the expression is known to yield only one entry.
226
+ Fetches the result of a query expression that yields one entry.
220
227
221
228
If no attributes are specified, returns the result as a dict.
222
229
If attributes are specified returns the corresponding results as a tuple.
@@ -225,7 +232,8 @@ def __call__(self, *attrs, squeeze=False, download_path='.'):
225
232
d = rel.fetch1() # as a dictionary
226
233
a, b = rel.fetch1('a', 'b') # as a tuple
227
234
228
- :params *attrs: attributes to return when expanding into a tuple. If empty, the return result is a dict
235
+ :params *attrs: attributes to return when expanding into a tuple.
236
+ If attrs is empty, the return result is a dict
229
237
:param squeeze: When true, remove extra dimensions from arrays in attributes
230
238
:param download_path: for fetches that download data, e.g. attachments
231
239
:return: the one tuple in the relation in the form of a dict
@@ -236,17 +244,20 @@ def __call__(self, *attrs, squeeze=False, download_path='.'):
236
244
cur = self ._expression .cursor (as_dict = True )
237
245
ret = cur .fetchone ()
238
246
if not ret or cur .fetchone ():
239
- raise DataJointError ('fetch1 should only be used for relations with exactly one tuple ' )
247
+ raise DataJointError ('fetch1 requires exactly one tuple in the input set. ' )
240
248
ret = dict ((name , _get (self ._expression .connection , heading [name ], ret [name ],
241
249
squeeze = squeeze , download_path = download_path ))
242
250
for name in heading .names )
243
251
else : # fetch some attributes, return as tuple
244
252
attributes = [a for a in attrs if not is_key (a )]
245
- result = self ._expression .proj (* attributes ).fetch (squeeze = squeeze , download_path = download_path )
253
+ result = self ._expression .proj (* attributes ).fetch (
254
+ squeeze = squeeze , download_path = download_path )
246
255
if len (result ) != 1 :
247
- raise DataJointError ('fetch1 should only return one tuple. %d tuples were found' % len (result ))
256
+ raise DataJointError (
257
+ 'fetch1 should only return one tuple. %d tuples found' % len (result ))
248
258
return_values = tuple (
249
- next (to_dicts (result [self ._expression .primary_key ])) if is_key (attribute ) else result [attribute ][0 ]
259
+ next (to_dicts (result [self ._expression .primary_key ]))
260
+ if is_key (attribute ) else result [attribute ][0 ]
250
261
for attribute in attrs )
251
262
ret = return_values [0 ] if len (attrs ) == 1 else return_values
252
263
return ret
0 commit comments