Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion datajoint/autopopulate.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,13 @@ def populate(self, restriction=None, suppress_errors=False,
table_name = self.target.table_name
keys = (todo - self.target.project()).fetch.keys()
if order == "reverse":
keys = list(keys).reverse()
keys = list(keys)
keys.reverse()
elif order == "random":
keys = list(keys)
random.shuffle(keys)
elif order != "original":
raise DataJointError('Invalid order specification')

for key in keys:
if not reserve_jobs or jobs.reserve(table_name, key):
Expand Down
25 changes: 13 additions & 12 deletions datajoint/base_relation.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ def insert(self, rows, replace=False, ignore_errors=False, skip_duplicates=False

"""
heading = self.heading
field_list = None
field_list = None # ensures that all rows have the same attributes in the same order as the first row.

def make_row_to_insert(row):
"""
Expand All @@ -205,8 +205,8 @@ def make_row_to_insert(row):

def make_placeholder(name, value):
"""
For a given attribute `name` with `value, return its processed value or value placeholder
as a string to be included in the query and the value, if any to be submitted for
For a given attribute `name` with `value`, return its processed value or value placeholder
as a string to be included in the query and the value, if any, to be submitted for
processing by mysql API.
:param name:
:param value:
Expand Down Expand Up @@ -237,13 +237,8 @@ def check_fields(fields):
for field in fields:
if field not in heading:
raise KeyError(u'{0:s} is not in the attribute list'.format(field))
else:
if len(fields) < len(field_list):
raise KeyError('Inserted row is missing some attributes.')
for field in fields:
if field not in field_list:
raise KeyError(
u'{0:s} is not found among the attributes of the first inserted row'.format(field))
elif set(field_list) != set(fields):
raise DataJointError('Attempt to insert rows with different fields')

if isinstance(row, np.void): # np.array
check_fields(row.dtype.fields)
Expand All @@ -269,9 +264,15 @@ def check_fields(fields):
row_to_insert = dict(zip(('names', 'placeholders', 'values'), zip(*attributes)))
nonlocal field_list
if field_list is None:
# first row sets the composition of the field list
field_list = row_to_insert['names']
elif set(field_list) != set(row_to_insert['names']):
raise DataJointError('Attempt to insert rows with different fields')
else:
# reorder attributes in row_to_insert to match field_list
order = list(row_to_insert['names'].index(field) for field in field_list)
row_to_insert['names'] = list(row_to_insert['names'][i] for i in order)
row_to_insert['placeholders'] = list(row_to_insert['placeholders'][i] for i in order)
row_to_insert['values'] = list(row_to_insert['values'][i] for i in order)

return row_to_insert

def row_exists(row):
Expand Down
4 changes: 2 additions & 2 deletions datajoint/user_relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class Lookup(UserRelation):
"""

_prefix = '#'
_regexp = r'(?P<lookup>' + _prefix + _base_regexp.replace('TIER', 'lookup') + ')'
_regexp = r'(?P<lookup>' + _prefix + _base_regexp.replace('TIER', 'lookup') + ')'

@classproperty
def table_name(cls):
Expand Down Expand Up @@ -144,7 +144,7 @@ class Part(BaseRelation):
"""

_regexp = r'(?P<master>' + '|'.join([c._regexp for c in [Manual, Imported, Computed, Lookup]]) + r'){1,1}' \
+ '__' + r'(?P<part>' + _base_regexp + ')'
+ '__' + r'(?P<part>' + _base_regexp + ')'

_master = None

Expand Down