id fields do not get any validators by default, and if they did, it 
certainly would not be an IS_IN_DB validator (if anything, it would be 
IS_NOT_IN_DB, as id values must be unique). Can we see your table 
definition?

Is it possible the problem is instead with a reference field, which by 
default would have an IS_IN_DB validator and would therefore be required 
for an insert?

Anthony

On Monday, May 8, 2017 at 6:28:50 PM UTC-4, Joe Barnhart wrote:
>
> So I'm using "validate_and_insert" to, well, validate and insert some 
> values.  Its a simple function and easily understood:
>
>     def validate_and_insert(self, **fields):
>         response, new_fields = self._validate_fields(fields)
>         if not response.errors:
>             response.id = self.insert(**new_fields)
>         return response
>
> It relies on "_validate" to check the validators:
>
>     def _validate_fields(self, fields, defattr='default'):
>         response = Row()
>         response.id, response.errors = None, Row()
>         new_fields = copy.copy(fields)
>         for fieldname in self.fields:
>             default = getattr(self[fieldname], defattr)
>             if callable(default):
>                 default = default()
>             raw_value = fields.get(fieldname, default)
>             value, error = self[fieldname].validate(raw_value)
>             if error:
>                 response.errors[fieldname] = "%s" % error
>             elif value is not None:
>                 new_fields[fieldname] = value
>         return response, new_fields
>
> And here lies the problem.  The field "id" was NOT provided in the 
> "fields" argument since we are inserting values, i.e. we don't have an id 
> yet.  But in the loop "for fieldname in self.fields" we are looping through 
> ALL of the fields in the able, including "id".  It's clear the reason is to 
> process the "default" values for each field -- a good idea.  What's NOT a 
> good idea is processing the validator for "id" which defines "id" can't be 
> None.
>
> The default validator for "id" is an IS_IN_DB validator.  It fails when 
> the argument (value) is "None" in the following fragment:
>
>         else:
>             if field.type in ('id', 'integer'):
>                 if isinstance(value, (int, long)) or value.isdigit():
>                     value = int(value)
>
> The failure happens on if isinstance(value, (int, long)) or 
> value.isdigit():  The value "None" fails the first test, but "or" 
> requires both arguments be evaluated if the first test fails, so it goes on 
> to the second test, which gives an exception.
>
> I'm not sure how this ever worked, but I'm sure it did at one point. 
>  Maybe there was a regression.  This was done in web2py 2.14.6-stable.
>
> -- Joe
>

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to