ArangoDB-Community / pyArango

Python Driver for ArangoDB with built-in validation
https://pyarango.readthedocs.io/en/latest/
Apache License 2.0
238 stars 90 forks source link

set default values in document-collections? #161

Closed mvidalv closed 4 years ago

mvidalv commented 5 years ago

Hi, I'm trying to set default values for the fields in collections, so I can handle two cases: one to set a value to the current datetime() of the save, and the second, to set some default values in case they are not custom set with the payload. But is not working as I expect, don't know if because of bad implementation or because I understand it wrong.

Here the example code I use:

from pyArango.connection import *
from pyArango.validation import *
from pyArango.collection import *
import datetime

conn = Connection()
db = conn["test_db"]

class Areas(Collection):
    _validation = {
        'on_save' : True,
        'on_set' : False,
        'allow_foreign_fields' : True
    }
    _fields = {
        'name' : Field(default='', validators = [NotNull()]),
        'code': Field(),
        'datetime': Field(default=datetime.datetime.now()),
      }

a_col = db.createCollection('Areas')

input_doc = {'code': '888'}

a_doc = a_col.createDocument(input_doc)

# then, because I would like to validate before saving, I do this:
stor_a = a_doc._store
print stor_a.validate() # I get True

a_doc.save() # actually I don't get any error
print a_doc

print a_doc gives :

ArangoDoc '_id: Areas/5097299366372, _key: 5097299366372, _rev: _ZLzPzFe---': <store: {'code': '888'}>

I would actually expect that, by default an Area document will be {'name': '', 'datetime': ' the_current_time'}, so when I try to save a document of Area collection, if no previous name was set, I expect to get a validation error (because of NotNull()), and I also I expect 'datetime' to be filled 'automatically'. But when I save the document (see above), is like the 'default' value is not taken into account). If I give the document as input_doc = {'name':'', 'code': '888'}, then I get the error:


input_doc = {'name':'', 'code': '888'}
a_doc = a_col.createDocument(input_doc)
stor_a = a_doc._store
print stor_a.validate() # I get the error of NotNull()
#[...]
#pyArango.theExceptions.InvalidDocument: Unsuccesful validation:
#    name -> 'name' -> Field can't have a null value: ''. Errors: {}. Errors: {}

a_doc.save() # I also get the error of NotNull()
#[...]
#pyArango.theExceptions.InvalidDocument: Unsuccesful validation:
#    name -> 'name' -> Field can't have a null value: ''. Errors: {}. Errors: {}
tariqdaouda commented 4 years ago

Hi @mvidalv

I have just pushed udpates to the dev branch that fixes these issues. Notice the reject_empty_string in the validator.

from pyArango.connection import *
from pyArango.validation import *
from pyArango.collection import *
import datetime

conn = Connection(password="root", username="root")
try :
    db = conn.createDatabase("test_db")
except:
    db = conn["test_db"]

class Areas(Collection):
    _validation = {
        'on_save' : True,
        'on_set' : False,
        'allow_foreign_fields' : True
    }
    _fields = {
        'name' : Field(default='', validators = [NotNull(reject_empty_string=False)]),
        'code': Field(),
        'datetime': Field(default=datetime.datetime.now()),
      }

try :
    a_col = db.createCollection('Areas')
except:
    a_col = db['Areas']

input_doc = {'code': '888'}

# a_doc = a_col.createDocument()
a_doc = a_col.createDocument(input_doc)

# then, because I would like to validate before saving, I do this:
stor_a = a_doc._store
print(stor_a.validate()) # I get True

a_doc.save() # actually I don't get any error
print(a_doc)