如何使用SQLAlchemy插入JSONB'执行'?

时间:2017-09-03 19:47:27

标签: python postgresql sqlalchemy jsonb

我需要运行一个带整数和JSONB数据的函数。 在普通的控制台中,我会像这样运行它:

select my_func(0, '{"foo": "bar"}'::jsonb)

这就是我认为它在SQLAlchemy中的作用:

params = {'p1': 0, 'p2': JSONB('{"foo": "bar"}'))}
result = db.engine.execute(text('select my_func(:p1, :p2)'), params)

但事实并非如此。我怎么能让SQLAlchemy理解它是我试图插入的JSONB?

1 个答案:

答案 0 :(得分:3)

JSONB用于定义列的类型,而不是处理值。使用文本SQL和需要特殊处理的类型时,Python或SQL端使用TextClause.bindparams()方法提供其他类型信息:

params = { 'p1': 0, 'p2': { "foo": "bar" } }
result = db.engine.execute(
    text('select my_func(:p1, :p2)').bindparams(
        bindparam('p2', type_=JSONB)),
    params)

请注意,您应该传递字典而不自行序列化。不使用bindparams()为SQLAlchemy提供类型信息,您的绑定值就像使用文本SQL时一样传递给DB-API游标。从这个角度来看,这也应该有效:

params = {'p1': 0, 'p2': '{"foo": "bar"}'}
result = db.engine.execute(
    text('select my_func(:p1, cast(:p2 as jsonb))'),
    params)

DB-API驱动程序看到字符串绑定值并像往常一样处理它。 SQL中的显式强制转换也可能是多余的。