SQLAlchemy version: 1.2.10, PostgreSQL vertsion: 10-something.
I'm following the documentation example from here
In [1]: import sqlalchemy as sa
In [2]: from nimble_core.backend.persistence.pg import PG_META_DATA
In [3]: data_table = sa.Table('data_table', PG_META_DATA,
   ...:     sa.Column('id', sa.Integer, primary_key=True),
   ...:     sa.Column('data', sa.JSON)
   ...: )
In [4]: data_table.create()
In [5]: with PG_ENGINE.connect() as conn:
   ...:     conn.execute(
   ...:         data_table.insert(),
   ...:         data = {"key1": "value1", "key2": "value2"}
   ...:     )
   ...:
Where:
In [10]: PG_ENGINE
Out[10]: Engine(postgresql://nimble:***@localhost:5432/nimble)
In [11]: PG_META_DATA
Out[11]: MetaData(bind=Engine(postgresql://nimble:***@localhost:5432/nimble))
In [12]: PG_META_DATA.sorted_tables
Out[12]:
[Table('data_table', MetaData(bind=Engine(postgresql://nimble:***@localhost:5432/nimble)), Column('id', Integer(), table=<data_table>, primary_key=True, nullable=False), Column('data', JSON(), table=<data_table>), schema=None)]
After the insertion operation, the table has a single row:
    In [14]: PG_ENGINE.execute(sa.select([data_table])).fetchall()
    Out[14]: [(1, {u'key2': u'value2', u'key1': u'value1'})]
The next thing I'm trying to do is to query rows by the value under a specific key in my JSON column, following this example:
In [17]: PG_ENGINE.execute(
    ...:     sa.select([data_table]).where(
    ...:         data_table.c.data['key1'].astext == 'value1'
    ...:     )
    ...: )
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-17-3c4db8afed3f> in <module>()
      1 PG_ENGINE.execute(
      2     sa.select([data_table]).where(
----> 3         data_table.c.data['key1'].astext == 'value1'
      4     )
      5 )
/Users/psih/Work/nimble-server/runtime/lib/python2.7/site-packages/sqlalchemy/sql/elements.pyc in __getattr__(self, key)
    686                     type(self).__name__,
    687                     type(self.comparator).__name__,
--> 688                     key)
    689             )
    690
AttributeError: Neither 'BinaryExpression' object nor 'Comparator' object has an attribute 'astext'
Obviously the type of a data_table.c.data['key1'] is something (sqlalchemy.sql.elements.BinaryExpression) that doesn't have the property astext. Does it mean that the documentation is wrong?
You are using sqlalchemy.types.JSON that does not have astext. Use sqlalchemy.dialects.postgresql.JSON instead
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
data_table = sa.Table('data_table', PG_META_DATA,
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('data', postgresql.JSON)
)
                        You can use raw sql in sqlalchemy filter
from sqlalchemy import text
db.session.query(DataTable).filter(text("data->['key1'] = 'value1'")
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With