On Mon, May 20, 2013 at 5:05 PM, Frank Millman <fr...@chagford.com> wrote: > Hi all > > I am trying to emulate a SQL check constraint in Python. Quoting from the > PostgreSQL docs, "A check constraint is the most generic constraint type. It > allows you to specify that the value in a certain column must satisfy a > Boolean (truth-value) expression." > > The problem is that I want to store the constraint as a string, and I was > hoping to use ast.literal_eval to evaluate it, but it does not work. > >>>> x = 'abc' >>>> x in ('abc', xyz') > True >>>> b = "x in ('abc', 'xyz')" >>>> eval(b) > True >>>> from ast import literal_eval >>>> literal_eval(b) > ValueError: malformed node or string: <_ast.Compare object at ...> > > Is there a safe way to do what I want? I am using python 3.3.
An SQL constraint has a whole lot that Python can't do conveniently, and vice versa, so I think you do yourself a disservice by trying to tie yourself to that. The problem here is that 'in' is an operator, so this is not a literal. One possible solution would be to separate out your operator (and have just a handful permitted), and then use ast.literal_eval for just the second operand - something like this: import ast import operator ops = { 'in':lambda x,y: x in y, # operator.contains has the args backwards '==':operator.eq, # or use '=' for more SQL-like syntax '<':operator.lt, '>':operator.gt, } op, value = 'in', "('abc', 'xyz')" x = 'abc' if ops[op](x,ast.literal_eval(value)): print("Constraint passed") else: print("Ignore this one") ChrisA -- http://mail.python.org/mailman/listinfo/python-list