A PostgreSQL hstore maintains order between storage and retrieval. This allows one to define the order in which the keys/values within the hstore are stored and retrieved.
Unfortunately, psycopg2's implementation uses a hard-coded dict under extras.py -> HstoreAdapter.parse()
.
While in most scenarios parsing an hstore to a dict suites just fine, in our scenario this causes problems; we specifically need to maintain ordering.
One work-around I've derived is querying for keys and values as separate lists:
SELECT AKEYS(myhstore) AS keys, AVALS(mystoore) AS vals FROM mytbl
... However that solution treats the symptom of the problem rather than the cause.
Is anyone aware of a monkey-patch solution to this issue, or a branch of psycopg2 which deals with this issue, or of an implementation of the extras.py file which resolves this?
Alternately, does anyone have any other suggestions on how to handle this?
NOTICE:
HSTORE
does not preserve order. It is unordered like Python'sdict
. My previous answer only worked by chance.Example:
All result in:
Which appears to be unordered because its order is different from the original order, and it is not alphabetically ordered.
THE BELOW DOES NOT ACTUALLY WORK!
You can maintain order in an
HSTORE
by using thehstore_to_matrix()
function which converts theHSTORE
to an array of key-value pairs. Then you have to manually pass it toOrderedDict
in Python:psycopg2
ultimately calls.keys()
and.values()
on the dictionary when its converted back to anHSTORE
which means so long as the dictionary is ordered, theHSTORE
sent back to PostgreSQL will also be ordered. You just have to pass back anOrderedDict
instead of a regulardict
to maintain order: