Question about ast.literal_eval
Chris Angelico
rosuav at gmail.com
Mon May 20 03:38:18 EDT 2013
On Mon, May 20, 2013 at 5:05 PM, Frank Millman <frank at 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
More information about the Python-list
mailing list