我在postgres数据库上使用sqlalchemy,我试图在两个表示浮点数的JSON字段的SELECT
中进行算术运算。但是,我还没有想出如何使这项工作。sqlalchemy/postgres:JSON字段上的算术?
假设我已经正确定义的表中调用transactions
,内含cost_data
一个JSON柱,并假定此JSON结构包含两个属性称为cost
和subtotal
代表的浮点值。
在SELECT
声明,我产生这两个字段的总和如下:
(cast(transactions.c.cost_data['subtotal'], sqlalchemy.Float) + cast(transactions.c.cost_data['cost'], sqlalchemy.Float)).label('total_cost')
这将生成以下SQL片段...
CAST((transactions.cost_data -> %(cost_data_6)s) AS FLOAT) + CAST((transactions.cost_data -> %(cost_data_7)s) AS FLOAT) AS total_cost
(其中cost_data_6
和cost_data_7
被置分别为subtotal
和cost
)。
不过,我得到以下错误:
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) cannot cast type json to double precision
如果我删除了铸造和做如下,它也失败...
(transactions.c.cost_data['subtotal'] + transactions.c.cost_data['cost']).label('total_cost')
我得到这个错误...
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) operator does not exist: json || json
LINE 9: ... (transactions.cost_data -> 'subtotal') || (transa...
^
显然,这是因为字段以字符串形式出现,“+”运算符被解释为字符串concatenat离子。
另外,如果我使用Python float
运营商,它也失败...
(float(transactions.c.cost_data['subtotal']) + float(transactions.c.cost_data['cost'])).label('total_cost')
Python解释器甚至不执行的代码,它给这个错误:
TypeError: float() argument must be a string or a number, not 'BinaryExpression'
那么如何使用sqlalchemy执行这两个字段的添加?
PS:下面是一个典型的cost_data
列值...
{"cost":3.99,"subtotal":12.34}
注意,金钱和浮点可能是一个糟糕的比赛。 [你可以用数字代替](https://stackoverflow.com/questions/45689496/query-a-specific-json-column-postgres-with-sqlalchemy)。 –
一致同意。在这种情况下,我无法更改数据库列定义,而其他软件使用这些字段的浮点数。 – HippoMan