Verify string lengths when creating model objects
This commit is contained in:
parent
f9686c5306
commit
5d1b5f90ac
2 changed files with 57 additions and 0 deletions
|
|
@ -17,6 +17,7 @@ from sqlservice import ModelBase, as_declarative
|
||||||
from pyjeeves import logging
|
from pyjeeves import logging
|
||||||
|
|
||||||
from . import db
|
from . import db
|
||||||
|
from .ext import InstallValidatorListeners
|
||||||
|
|
||||||
logger = logging.getLogger("PyJeeves." + __name__)
|
logger = logging.getLogger("PyJeeves." + __name__)
|
||||||
|
|
||||||
|
|
@ -37,6 +38,7 @@ except OperationalError as e:
|
||||||
class RawBaseModel(ModelBase):
|
class RawBaseModel(ModelBase):
|
||||||
""" Generalize __init__, __repr__ and to_json
|
""" Generalize __init__, __repr__ and to_json
|
||||||
Based on the models columns , ForetagKod=1"""
|
Based on the models columns , ForetagKod=1"""
|
||||||
|
__sa_instrumentation_manager__ = InstallValidatorListeners
|
||||||
|
|
||||||
__to_dict_filter__ = []
|
__to_dict_filter__ = []
|
||||||
__to_dict_only__ = ()
|
__to_dict_only__ = ()
|
||||||
|
|
|
||||||
55
pyjeeves/models/ext.py
Normal file
55
pyjeeves/models/ext.py
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
from sqlalchemy.ext.instrumentation import InstrumentationManager
|
||||||
|
# from sqlalchemy.orm.interfaces import AttributeExtension
|
||||||
|
from sqlalchemy.orm import ColumnProperty
|
||||||
|
from sqlalchemy.types import String
|
||||||
|
from sqlalchemy import event
|
||||||
|
|
||||||
|
|
||||||
|
class Error(Exception):
|
||||||
|
"""Base class for exceptions in this module."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ValidationError(Error):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class JeevesDBError(Error):
|
||||||
|
"""Exception raised for errors in the input.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
expression -- input expression in which the error occurred
|
||||||
|
message -- explanation of the error
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, field, message):
|
||||||
|
super().__init__(message)
|
||||||
|
self.field = field
|
||||||
|
self.message = message
|
||||||
|
|
||||||
|
|
||||||
|
class InstallValidatorListeners(InstrumentationManager):
|
||||||
|
def post_configure_attribute(self, class_, key, inst):
|
||||||
|
"""Add validators for any attributes that can be validated."""
|
||||||
|
prop = inst.prop
|
||||||
|
# Only interested in simple columns, not relations
|
||||||
|
if isinstance(prop, ColumnProperty) and len(prop.columns) == 1:
|
||||||
|
col = prop.columns[0]
|
||||||
|
# if we have string column with a length, create a length validator listner
|
||||||
|
if isinstance(col.type, String) and col.type.length:
|
||||||
|
event.listen(
|
||||||
|
getattr(class_, key), 'set', LengthValidator(
|
||||||
|
col.name, col.type.length), retval=True)
|
||||||
|
|
||||||
|
|
||||||
|
class LengthValidator():
|
||||||
|
def __init__(self, col_name, max_length):
|
||||||
|
self.col_name = col_name
|
||||||
|
self.max_length = max_length
|
||||||
|
|
||||||
|
def __call__(self, state, value, oldvalue, initiator):
|
||||||
|
if len(value) > self.max_length:
|
||||||
|
raise ValidationError(
|
||||||
|
"%s.%s: Length %d exceeds allowed %d" % (
|
||||||
|
state.__class__.__name__, self.col_name, len(value), self.max_length))
|
||||||
|
return value
|
||||||
Loading…
Add table
Add a link
Reference in a new issue