Skip to content
This repository has been archived by the owner on Aug 27, 2023. It is now read-only.

Commit

Permalink
New parameter 'no_read=True' for sync() operation
Browse files Browse the repository at this point in the history
  • Loading branch information
stevearc committed Sep 10, 2015
1 parent e13d1a4 commit 5cf757e
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 8 deletions.
6 changes: 6 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Changelog
=========

0.5.0
-----
* **Breakage**: Removing support for overflow fields. The only fields flywheel will care about now are those that are explicitly set as a Field()
* Flywheel no longer forces raise_on_conflict to be True when you sync changes to fields that are part of a composite field. It is now up to the user to avoid putting their composite fields into an inconsistent state.
* Feature: sync() has a new argument, ``no_read``, which changes the behavior for syncing models with no changes. Instead of performing a GET, it will leave them as-is. This should make it easer to perform batch syncs without worrying as much about wasted bandwidth on GETs.

0.4.3
-----
* Bug fix: Incorrect ``ConditionalCheckFailedException`` when syncing changes to a Composite field.
Expand Down
11 changes: 8 additions & 3 deletions flywheel/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,8 @@ def refresh(self, items, consistent=False):
for key, val in data.items():
item.set_ddb_val_(key, val)

def sync(self, items, raise_on_conflict=None, consistent=False, constraints=None):
def sync(self, items, raise_on_conflict=None, consistent=False,
constraints=None, no_read=False):
"""
Sync model changes back to database
Expand All @@ -517,11 +518,14 @@ def sync(self, items, raise_on_conflict=None, consistent=False, constraints=None
List of more complex constraints that must pass for the update to
complete. Must be used with raise_on_conflict=True. Format is the
same as query filters (e.g. Model.fieldname > 5)
no_read : bool, optional
If True, don't perform a GET on models with no changes. (default False)
Raises
------
exc : :class:`dynamo3.CheckFailed`
If raise_on_conflict=True and the model changed underneath us
If raise_on_conflict=True and the data in dynamo fails the
contraint checks.
"""
if raise_on_conflict is None:
Expand Down Expand Up @@ -600,4 +604,5 @@ def sync(self, items, raise_on_conflict=None, consistent=False, constraints=None
except CheckFailed:
pass
# Refresh item data
self.refresh(refresh_models, consistent=consistent)
if not no_read:
self.refresh(refresh_models, consistent=consistent)
9 changes: 4 additions & 5 deletions flywheel/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,19 +143,18 @@ def refresh(self, consistent=False):

self.__engine__.refresh(self, consistent=consistent)

def sync(self, raise_on_conflict=None, constraints=None):
def sync(self, *args, **kwargs):
""" Sync model changes back to database """
if self.__engine__ is None:
raise ValueError("Cannot sync: No DB connection")

self.__engine__.sync(self, raise_on_conflict=raise_on_conflict,
constraints=constraints)
self.__engine__.sync(self, *args, **kwargs)

def delete(self, raise_on_conflict=None):
def delete(self, *args, **kwargs):
""" Delete the model from the database """
if self.__engine__ is None:
raise ValueError("Cannot delete: No DB connection")
self.__engine__.delete(self, raise_on_conflict=raise_on_conflict)
self.__engine__.delete(self, *args, **kwargs)

@classmethod
def __on_create__(cls):
Expand Down
20 changes: 20 additions & 0 deletions tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,26 @@ def test_delattr_private_field(self):
del a._foobar
self.assertFalse(hasattr(a, '_foobar'))

def test_sync_refresh(self):
""" Syncing a model with no changes will refresh the data """
a = Article(text='foo')
self.engine.save(a)
a2 = self.engine.scan(Article).first()
a2.text = 'bar'
self.engine.sync(a2)
a.sync()
self.assertEqual(a.text, 'bar')

def test_sync_no_read(self):
""" Sync(no_read=True) performs a write and no reads """
a = Article(text='foo')
self.engine.save(a)
a2 = self.engine.scan(Article).first()
a2.text = 'bar'
self.engine.sync(a2)
a.sync(no_read=True)
self.assertEqual(a.text, 'foo')


class Store(Model):

Expand Down

0 comments on commit 5cf757e

Please sign in to comment.