Skip to content

Commit 57eba56

Browse files
committed
Merge branch 'dev'
2 parents db758bf + ba414b7 commit 57eba56

File tree

7 files changed

+78
-69
lines changed

7 files changed

+78
-69
lines changed

CHANGELOG.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
2.0.1
2+
=====
3+
4+
* Fixed max retries for write conflicts
5+
6+
2.0
7+
=====
8+
9+
* changed the default value of reject_zero in NotNull from True to False
10+
* added to_default function to reset a document to its default values
11+
* fixed bug in default documents where default values could be overwritten
12+
* default value for fields is now None
13+
* defaual value for fields can now be a callable
14+
115
1.3.5
216
=====
317

pyArango/collection.py

Lines changed: 25 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ def __repr__(self):
118118

119119
class Field(object):
120120
"""The class for defining pyArango fields."""
121-
def __init__(self, validators = None, default = ""):
122-
"""validators must be a list of validators"""
121+
def __init__(self, validators = None, default = None):
122+
"""validators must be a list of validators. default can also be a callable"""
123123
if not validators:
124124
validators = []
125125
self.validators = validators
@@ -238,16 +238,6 @@ class Collection(with_metaclass(Collection_metaclass, object)):
238238

239239
def __init__(self, database, jsonData):
240240

241-
def getDefaultDoc(fields, dct):
242-
for k, v in fields.items():
243-
if isinstance(v, dict):
244-
dct[k] = getDefaultDoc(fields[k], {})
245-
elif isinstance(v, Field):
246-
dct[k] = v.default
247-
else:
248-
raise ValueError("Field '%s' is of invalid type '%s'" % (k, type(v)) )
249-
return dct
250-
251241
self.database = database
252242
self.connection = self.database.connection
253243
self.name = self.__class__.__name__
@@ -267,13 +257,30 @@ def getDefaultDoc(fields, dct):
267257
"fulltext" : {},
268258
}
269259
self.indexes_by_name = {}
270-
271-
self.defaultDocument = getDefaultDoc(self._fields, {})
260+
# self.defaultDocument = None #getDefaultDoc(self._fields, {})
272261
self._isBulkInProgress = False
273262
self._bulkSize = 0
274263
self._bulkCache = []
275264
self._bulkMode = BulkMode.NONE
276265

266+
def getDefaultDocument(self, fields=None, dct=None):
267+
if dct is None:
268+
dct = {}
269+
if fields is None:
270+
fields = self._fields
271+
272+
for k, v in fields.items():
273+
if isinstance(v, dict):
274+
dct[k] = self.getDefaultDocument(fields[k], None)
275+
elif isinstance(v, Field):
276+
if callable(v.default):
277+
dct[k] = v.default()
278+
else :
279+
dct[k] = v.default
280+
else:
281+
raise ValueError("Field '%s' is of invalid type '%s'" % (k, type(v)) )
282+
return dct
283+
277284
def getURL(self):
278285
return "%s/collection/%s" % (self.database.getURL(), self.name)
279286

@@ -316,7 +323,9 @@ def delete(self):
316323

317324
def createDocument(self, initDict = None):
318325
"""create and returns a completely empty document or one populated with initDict"""
319-
res = dict(self.defaultDocument)
326+
# res = dict(self.defaultDocument)
327+
res = self.getDefaultDocument()
328+
320329
if initDict is not None:
321330
res.update(initDict)
322331

@@ -638,55 +647,6 @@ def validatePrivate(self, field, value):
638647
self._fields[field].validate(value)
639648
return True
640649

641-
# @classmethod
642-
# def validateField(cls, fieldName, value):
643-
# """checks if 'value' is valid for field 'fieldName'. If the validation is unsuccessful, raises a SchemaViolation or a ValidationError.
644-
# for nested dicts ex: {address : { street: xxx} }, fieldName can take the form address.street
645-
# """
646-
647-
# def _getValidators(cls, fieldName):
648-
# path = fieldName.split(".")
649-
# v = cls._fields
650-
# for k in path:
651-
# try:
652-
# v = v[k]
653-
# except KeyError:
654-
# return None
655-
# return v
656-
657-
# field = _getValidators(cls, fieldName)
658-
659-
# if field is None:
660-
# if not cls._validation["allow_foreign_fields"]:
661-
# raise SchemaViolation(cls, fieldName)
662-
# else:
663-
# return field.validate(value)
664-
665-
# @classmethod
666-
# def validateDct(cls, dct):
667-
# "validates a dictionary. The dictionary must be defined such as {field: value}. If the validation is unsuccefull, raises an InvalidDocument"
668-
# def _validate(dct, res, parentsStr=""):
669-
# for k, v in dct.items():
670-
# if len(parentsStr) == 0:
671-
# ps = k
672-
# else:
673-
# ps = "%s.%s" % (parentsStr, k)
674-
675-
# if type(v) is dict:
676-
# _validate(v, res, ps)
677-
# elif k not in cls.arangoPrivates:
678-
# try:
679-
# cls.validateField(ps, v)
680-
# except (ValidationError, SchemaViolation) as e:
681-
# res[k] = str(e)
682-
683-
# res = {}
684-
# _validate(dct, res)
685-
# if len(res) > 0:
686-
# raise InvalidDocument(res)
687-
688-
# return True
689-
690650
@classmethod
691651
def hasField(cls, fieldName):
692652
"""returns True/False wether the collection has field K in it's schema. Use the dot notation for the nested fields: address.street"""
@@ -982,3 +942,4 @@ def __enter__(self):
982942
return self.coll
983943
def __exit__(self, type, value, traceback):
984944
self.coll._finalizeBatch();
945+

pyArango/connection.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
from .ca_certificate import CA_Certificate
1616

17+
from json.decoder import JSONDecodeError
18+
1719
class JsonHook(object):
1820
"""This one replaces requests' original json() function. If a call to json() fails, it will print a message with the request content"""
1921
def __init__(self, ret):
@@ -50,11 +52,17 @@ def __call__(self, *args, **kwargs):
5052
kwargs["verify"] = self.verify
5153

5254
try:
53-
status_code = 1200
55+
do_retry = True
5456
retry = 0
55-
while status_code == 1200 and retry < self.max_conflict_retries :
57+
while do_retry and retry < self.max_conflict_retries :
5658
ret = self.fct(*args, **kwargs)
57-
status_code = ret.status_code
59+
do_retry = ret.status_code == 1200
60+
try :
61+
data = ret.json()
62+
do_retry = do_retry or ("errorNum" in data and data["errorNum"] == 1200)
63+
except JSONDecodeError:
64+
pass
65+
5866
retry += 1
5967
except:
6068
print ("===\nUnable to establish connection, perhaps arango is not running.\n===")

pyArango/document.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,10 @@ def reset(self, collection, jsonFieldInit = None, on_load_validation=False) :
230230

231231
self.modified = True
232232

233+
def to_default(self):
234+
"""reset the document to the default values"""
235+
self.reset(self.collection, self.collection.getDefaultDocument())
236+
233237
def validate(self):
234238
"""validate the document"""
235239
self._store.validate()

pyArango/tests/tests.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,28 @@ def deleteManyUsersBulk(self, collection, batchSize, skip, docs):
101101
count += 1
102102
return count
103103

104+
# @unittest.skip("stand by")
105+
def test_to_default(self):
106+
class theCol(Collection):
107+
_fields = {
108+
'address' : {
109+
'street' : Field(default="Paper street"),
110+
},
111+
"name": Field(default = "Tyler Durden")
112+
}
113+
114+
col = self.db.createCollection("theCol")
115+
doc = col.createDocument()
116+
self.assertEqual(doc["address"]["street"], "Paper street")
117+
self.assertEqual(doc["name"], "Tyler Durden")
118+
doc["address"]["street"] = "North street"
119+
doc["name"] = "Jon Snow"
120+
self.assertEqual(doc["address"]["street"], "North street")
121+
self.assertEqual(doc["name"], "Jon Snow")
122+
doc.to_default()
123+
self.assertEqual(doc["address"]["street"], "Paper street")
124+
self.assertEqual(doc["name"], "Tyler Durden")
125+
104126
# @unittest.skip("stand by")
105127
def test_bulk_operations(self):
106128
(collection, docs) = self.createManyUsersBulk(55, 17)

pyArango/validation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def __str__(self):
1515

1616
class NotNull(Validator):
1717
"""Checks that the Field has a non null value. False is not considered a Null Value"""
18-
def __init__(self, reject_zero=True, reject_empty_string=True):
18+
def __init__(self, reject_zero=False, reject_empty_string=True):
1919
self.reject_zero = reject_zero
2020
self.reject_empty_string = reject_empty_string
2121

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
setup(
1212
name='pyArango',
1313

14-
version='1.3.5',
14+
version='2.0.1',
1515

1616
description='An easy to use python driver for ArangoDB with built-in validation',
1717
long_description=long_description,

0 commit comments

Comments
 (0)