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
2 changes: 1 addition & 1 deletion morango/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
from __future__ import unicode_literals

default_app_config = "morango.apps.MorangoConfig"
__version__ = "0.4.9"
__version__ = "0.4.11"
17 changes: 13 additions & 4 deletions morango/sync/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from django.core import exceptions
from django.core.serializers.json import DjangoJSONEncoder
from django.db import connection
from django.db import connections
from django.db import router
from django.db import transaction
from django.db.models import Q
from django.db.models import signals
Expand All @@ -29,6 +31,13 @@

DBBackend = load_backend(connection).SQLWrapper()

# if postgres, get serializable db connection
db_name = router.db_for_write(Store)
USING_DB = db_name
if "postgresql" in transaction.get_connection(USING_DB).vendor:
USING_DB = db_name + '-serializable'
assert USING_DB in connections, "Please add a `default-serializable` database connection in your django settings file, \
which copies all the configuration settings of the `default` db connection"

def _join_with_logical_operator(lst, operator):
op = ") {operator} (".format(operator=operator)
Expand Down Expand Up @@ -70,7 +79,7 @@ def _serialize_into_store(profile, filter=None):
# ensure that we write and retrieve the counter in one go for consistency
current_id = InstanceIDModel.get_current_instance_and_increment_counter()

with transaction.atomic():
with transaction.atomic(using=USING_DB):
# create Q objects for filtering by prefixes
prefix_condition = None
if filter:
Expand Down Expand Up @@ -227,7 +236,7 @@ def _deserialize_from_store(profile):

logger.info("Deserializing records")
fk_cache = {}
with transaction.atomic():
with transaction.atomic(using=USING_DB):
excluded_list = []
# iterate through classes which are in foreign key dependency order
for model in syncable_models.get_models(profile):
Expand Down Expand Up @@ -316,7 +325,7 @@ def _deserialize_from_store(profile):
logger.info("Deserialization complete")


@transaction.atomic()
@transaction.atomic(using=USING_DB)
def _queue_into_buffer(transfersession):
"""
Takes a chunk of data from the store to be put into the buffer to be sent to another morango instance.
Expand Down Expand Up @@ -399,7 +408,7 @@ def _queue_into_buffer(transfersession):
logger.info("Queuing complete")


@transaction.atomic()
@transaction.atomic(using=USING_DB)
def _dequeue_into_store(transfersession):
"""
Takes data from the buffers and merges into the store and record max counters.
Expand Down
23 changes: 22 additions & 1 deletion tests/testapp/testapp/postgres_test.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
"""
A settings module for running tests using a postgres db backend.
"""
from __future__ import absolute_import, print_function, unicode_literals
from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals

try:
isolation_level = None
import psycopg2
isolation_level = psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE
except ImportError:
pass

from .settings import * # noqa

Expand All @@ -15,4 +24,16 @@
'NAME': 'travis_ci_default'
}
},
'default-serializable': {
'ENGINE': 'django.db.backends.postgresql',
'USER': 'postgres',
'PASSWORD': '',
'NAME': 'default', # This module should never be used outside of tests -- so this name is irrelevant
'TEST': {
'NAME': 'travis_ci_default'
},
'OPTIONS': {
'isolation_level': isolation_level,
}
}
}