Skip to content

Commit

Permalink
Merge pull request kobotoolbox#974 from kobotoolbox/multiple-objects-…
Browse files Browse the repository at this point in the history
…returned-error

Fixes "AssetSnapshot.MultipleObjectsReturned" error.
  • Loading branch information
jnm authored Oct 18, 2016
2 parents 2a49fe9 + c47c36f commit 96a0e1c
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 6 deletions.
21 changes: 21 additions & 0 deletions kpi/models/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,23 @@ def _populate_fields_with_autofields(self, content):
def _expand_kobo_qs(self, content):
expand_rank_and_score_in_place(content)

def _ensure_settings(self, content):
# asset.settings should exist already, but
# on some legacy forms it might not
_settings = content.get('settings', {})
if isinstance(_settings, list):
if len(_settings) > 0:
_settings = _settings[0]
else:
_settings = {}
if not isinstance(_settings, dict):
_settings = {}
content['settings'] = _settings

def _append(self, content, **sheet_data):
settings = sheet_data.pop('settings', None)
if settings:
self._ensure_settings(content)
content['settings'].update(settings)
for (sht, rows) in sheet_data.items():
if sht in content:
Expand Down Expand Up @@ -503,6 +517,7 @@ def version_id(self):
def snapshot(self):
return self._snapshot(regenerate=False)

@transaction.atomic
def _snapshot(self, regenerate=True):
asset_version = self.asset_versions.first()

Expand All @@ -517,6 +532,12 @@ def _snapshot(self, regenerate=True):
if regenerate:
snapshot.delete()
snapshot = False
except AssetSnapshot.MultipleObjectsReturned:
# how did multiple snapshots get here?
snaps = AssetSnapshot.objects.filter(asset=self,
asset_version=asset_version)
snaps.delete()
snapshot = False
except AssetSnapshot.DoesNotExist:
snapshot = False

Expand Down
9 changes: 3 additions & 6 deletions kpi/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,12 +327,9 @@ def create(self, validated_data):
if not self.context['request'].user.has_perm('view_asset', asset):
# The client is not allowed to snapshot this asset
raise exceptions.PermissionDenied
asset_version = asset.asset_versions.first()
try:
snapshot = AssetSnapshot.objects.get(asset=asset,
asset_version=asset_version)
except AssetSnapshot.DoesNotExist as e:
snapshot = AssetSnapshot.objects.create(**validated_data)
# asset.snapshot pulls , by default, a snapshot for the latest
# version.
snapshot = asset.snapshot
elif source:
# The client provided source directly; no need to copy anything
# For tidiness, pop off unused fields. `None` avoids KeyError
Expand Down

0 comments on commit 96a0e1c

Please sign in to comment.