![](/img/trans.png)
[英]Direct reference of column names in python using python, psycopg2, and postgresql
[英]Return PostgreSQL hstore as OrderedDict using psycopg2 in Python
PostgreSQL hstore維護存儲和檢索之間的順序。 這樣一來,就可以定義hstore中鍵/值的存儲和檢索順序。
不幸的是,psycopg2的實現在extras.py -> HstoreAdapter.parse()
下使用了硬編碼的dict。
在大多數情況下,將hstore解析為dict套件就可以了,但是在我們的情況下,這會引起問題; 我們特別需要保持訂購。
我得出的一種解決方法是,將鍵和值作為單獨的列表進行查詢:
SELECT AKEYS(myhstore) AS keys, AVALS(mystoore) AS vals FROM mytbl
...但是,該解決方案只處理問題的征兆,而不是原因。
有誰知道針對此問題的猴子補丁解決方案,或處理此問題的psycopg2分支,或解決此問題的extras.py文件的實現?
或者,是否有人對如何處理此問題有其他建議?
注意: HSTORE
不保留訂單。 它像Python的dict
一樣無序。 我以前的回答只是偶然的。
對的順序並不重要(並且可能不會在輸出中復制)。
例:
SELECT 'foo=>1,bar=>2,spam=>3,eggs=>4'::hstore
UNION ALL
SELECT hstore('{foo,1,bar,2,spam,3,eggs,4}'::TEXT[])
UNION ALL
SELECT hstore('{{foo,1},{bar,2},{spam,3},{eggs,4}}'::TEXT[])
UNION ALL
SELECT hstore('{foo,bar,spam,eggs}'::TEXT[], '{1,2,3,4}'::TEXT[])
全部導致:
""bar"=>"2", "foo"=>"1", "eggs"=>"4", "spam"=>"3""
""bar"=>"2", "foo"=>"1", "eggs"=>"4", "spam"=>"3""
""bar"=>"2", "foo"=>"1", "eggs"=>"4", "spam"=>"3""
""bar"=>"2", "foo"=>"1", "eggs"=>"4", "spam"=>"3""
由於它的順序與原始順序不同,並且它不是按字母順序排列的,因此它似乎是無序的。
下列內容無法正常工作!
您可以使用hstore_to_matrix()
函數將HSTORE
轉換為HSTORE
對數組,從而保持HSTORE
的順序。 然后,您必須手動將其傳遞給Python中的OrderedDict
:
import collections
import psycopg2
import psycopg2.extras
pg = psycopg2.connect(...)
psycopg2.extras.register_hstore(pg)
cursor = pg.cursor()
cursor.execute("""
SELECT hstore_to_matrix('a=>1,b=>2,c=>3'::hstore);
""")
pairs = cursor.fetchone()[0]
ordered = collections.OrderedDict(pairs)
print(pairs)
# [['a', '1'], ['b', '2'], ['c', '3']]
print(ordered)
# OrderedDict([('a', '1'), ('b', '2'), ('c', '3')])
psycopg2
轉換回HSTORE
, psycopg2
最終在字典上調用.keys()
和.values()
,這意味着只要對字典進行了訂購,也HSTORE
發送回PostgreSQL的HSTORE
進行訂購。 您只需要傳回OrderedDict
而不是常規dict
即可維持訂單:
# This will save the data as ordered.
data = OrderedDict([('a', '1'), ('b', '2'), ('c', '3')])
cursor.update("""
UPDATE mytable
SET ordered = %(data)s;
""", {
'data': data
})
# This will save the data as unordered. Whatever the internal order
# happens to be for the dict will be sent. When I run it in the python
# interpreter, it results in:
# [('a', '1'), ('c', '3'), ('b', '2')]
cursor.update("""
UPDATE mytable
SET ordered = %(data)s;
""", {
'data': data
})
你可以轉儲到字符串並存儲為文本
那么您可以在json解碼器中指定object_pairs_hook
: http : //docs.python.org/2/library/json.html#encoders-and-decoders
In [1]: json.JSONDecoder(object_pairs_hook=collections.OrderedDict).decode('{"foo":1, "bar": 2}')
Out[1]: OrderedDict([('foo', 1), ('bar', 2)])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.