PG JSONB as primary key and unhashables

239 views
Skip to first unread message

Rodrigo

unread,
Sep 6, 2016, 5:23:57 PM9/6/16
to sqlalchemy
Hi, everyone.

For more than a week I've been trying to get SQLAlchemy to work with Postgres while using JSONB as a primary key (actually, as part of a composite key). I've tried searching for a solution, but have been stumped for a few days.

If the JSONB attribute is not a key, everythin works just fine. But when I have my JSONB attribute set as primary key and try to insert something non-hashable like a dict, I get the error:

TypeError: unhashable type: 'dict'

Here's an excerpt of a test code that runs into that problem:

class Test(Base):
 __tablename__
= 'test'

 json
= Column(JSONB, primary_key=True)


session
= create_session()

j1
= { 'a': 1 }

t
= Test()

t
.json = j1

session
.merge(t)
session
.commit()

Here's the full stack trace:

Traceback (most recent call last):
 
File "test_pg_json.py", line 37, in <module>
 session
.merge(t)
 
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 1748, in merge
 _resolve_conflict_map
=_resolve_conflict_map)
 
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 1773, in _merge
 
if key in self.identity_map:
 
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/identity.py", line 97, in __contains__
 
if key in self._dict:
TypeError: unhashable type: 'dict'

Any ideas on how to solve that, or if that is even possible to do?

Thanks,

Rodrigo

Mike Bayer

unread,
Sep 7, 2016, 9:49:06 AM9/7/16
to sqlal...@googlegroups.com


On 09/06/2016 05:23 PM, Rodrigo wrote:
> Hi, everyone.
>
> For more than a week I've been trying to get SQLAlchemy to work with
> Postgres while using JSONB as a primary key (actually, as part of a
> composite key). I've tried searching for a solution, but have been
> stumped for a few days.
>
> If the JSONB attribute is not a key, everythin works just fine. But when
> I have my JSONB attribute set as primary key and try to insert something
> non-hashable like a dict, I get the error:
>
> |
> TypeError:unhashable type:'dict'
> |
>
> Here's an excerpt of a test code that runs into that problem:

The ORM requires that primary keys are hashable (the Core does not,
btw). You'd need to make yourself a wrapper around your JSONB datatype
(using TypeDecorator, most likely) that returns a structure that
provides a __hash__() method as well as an appropriate __eq__() method
if necessary.


>
> |
> classTest(Base):
> __tablename__ ='test'
>
> json =Column(JSONB,primary_key=True)
>
>
> session =create_session()
>
> j1 ={'a':1}
>
> t =Test()
>
> t.json =j1
>
> session.merge(t)
> session.commit()
> |
>
>
> Here's the full stack trace:
>
> |
> Traceback(most recent call last):
> File"test_pg_json.py",line 37,in<module>
> session.merge(t)
> File"/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py",line
> 1748,inmerge
> _resolve_conflict_map=_resolve_conflict_map)
> File"/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py",line
> 1773,in_merge
> ifkey inself.identity_map:
> File"/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/identity.py",line
> 97,in__contains__
> ifkey inself._dict:
> TypeError:unhashable type:'dict'
> |
>
> Any ideas on how to solve that, or if that is even possible to do?
>
> Thanks,
>
> Rodrigo
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to sqlalchemy+...@googlegroups.com
> <mailto:sqlalchemy+...@googlegroups.com>.
> To post to this group, send email to sqlal...@googlegroups.com
> <mailto:sqlal...@googlegroups.com>.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages