Making the unique validator with Coland and SQLAlchemy

278 views Asked by At

All I trying to do is simple blog website using Pyramid, SQLAlchemy. The form module I have chosen is Deform which uses Coland. So I have for now two fields in my form: name and url. Url creates by transliteration the name field, but it's nevermind. So I don't wanna have two articles with the same urls. I need somehow make the validator with Colland I think. But the problem is the validator performs per field, but not per Model record. I mean if I'd make validator for url field, I dont have information in my method about another fields, such as id or name, so I couldn't perform the validation.

For now I have there couple of strings I created for two hours =)

from slugify import slugify

def convertUrl(val):
    return slugify(val) if val else val


class ArticleForm(colander.MappingSchema):
    name = colander.SchemaNode(colander.String())
    url = colander.SchemaNode(colander.String(),
                              preparer=convertUrl)

Actually, I thought I should perform such validation on a model level, i.e. in SQLAlchemy model, but of course futher rules don't work, because such rules exist mainly for making SQL scripts (CREATE TABLE):

class Article(TBase, Base):
    """ The SQLAlchemy declarative model class for a Article object. """
    __tablename__ = 'article'

    id = Column(Integer, primary_key=True)
    name = Column(Text, unique=True)
    url = Column(Text, unique=True)
1

There are 1 answers

0
James May On

Actually my question doesn't refer neither to Deform nor to Colander, this validation must be performed at SQLAlchemy level, here's what i've come to:

@validates('url')
def validate_url_unique(self, key, value):
    check_unique = DBSession.query(Article)\
        .filter(and_(Article.url == value, Article.id != self.id)).first()

    if check_unique:
        # Doesn't work
        raise ValueError('Something went wrong')

    # Neither doesn't work
    # assert not check_unique

    return value