2015-04-25 26 views
5

JSG'ler dışa aktarılırken, Postgres hatalı bir şekilde tırnak işareti çıkarıyor.Postgres row_to_json, çift çıkışlı tırnak işaretleri içeren geçersiz JSON üretiyor

{"column":"\\"hello\\""} 

Sen tırnak yanlış kaçan olduğunu görebilir ve geçersiz JSON oluşturur: output.json ait

UPDATE models SET column='"hello"' WHERE id=1; 

COPY (SELECT row_to_json(models) 
    FROM (SELECT column FROM shaders WHERE id=1) shaders) 
    TO '/output.json'; 

içerik ... aşağıda güncellemede çift tırnak unutmayın. Olmalıdır:

{"column":"\"hello\""} 

nasıl etrafında bu Postgres hatayı veya iş düzeltebilirim?

+0

Bunu # 13160 hatası olarak http://www.postgresql.org/list/pgsql-bugs/ adresine gönderdim (beklemede kalma) –

+0

Hata değil. "COPY", tek bir sonucu bir dosyaya vermek değildir. Kaçak sıra odaklı veri yayar. Bunun yerine 'psql''' yerine' 'seçeneğini seçmiş gibi geliyor. –

cevap

7

JSON ile ilgili değil. Bu, COPY komutundaki metin biçiminin (varsayılan) ters eğik çizgileri işleme şekliyle ilgilidir. the PostgreSQL documentation - COPY Gönderen: Aksi satır veya sütun ayracı olarak alınabilir veri karakterleri alıntı KOPYA verilerinde kullanılabilecek

Backslash karakterler (\). Özellikle, aşağıdaki karakterlerin bir sütun değerinin bir parçası olarak göründükleri takdirde ters eğik çizgi olması gerekir: ters eğik çizgi kendisi, satırsonu dönüşü ve geçerli sınırlayıcı karakter.

(Vurgu benim.)
CSV-formatı kullanarak ve doublequote gelen başka bir şey tırnak karakteri değiştirerek bunu çözebilir.

göstermek için: eminseniz

SELECT row_to_json(row('"hello"')) 
| "{"f1":"\"hello\""}" | 


COPY (SELECT row_to_json(row('"hello"'))) TO '/output.json'; 
| {"f1":"\\"hello\\""} | 


COPY (SELECT row_to_json(row('"hello"'))) TO '/output.json' CSV QUOTE '$'; 
| {"f1":"\"hello\""} | 
+0

Önerilen çözümünüzün neler yaptığını açıklar mısınız? –

+1

Çözüm üçüncü satırda: 'COPY (SELECT row_to_json (satır ('" merhaba "'))) TO '/output.json' CSV QUOTE '$';' ve çalışmayan versiyona eklenen tek şey önceki satır 'CSV QUOTE '$''.Bu, varsayılan metin biçiminden farklı olarak ters eğik çizgilere ikinci ters eğik çizgi eklemeyen CSV biçimine dönüşür. CSV'de, varsayılan alıntı karakteri çift alıntıdır, bu nedenle başka bir şeye değiştirilmelidir - bu örnekte dolar işareti. –

+0

ama bu benim dizelerimde sahip olabileceğim herhangi bir dolar işaretinin bir ters eğik çizgi ile kalacağı anlamına gelmiyor mu? Büyük bir masa ihraç ediyorum ve aslında% 100 kesinlikle görünmeyecek özel bir karakter yok. Bir şekilde kaçmak sadece devre dışı bırakılabilir mi? –

2

Simo Kivistö tarafından cevap çalışır karakteri $, ya da her türlü özel alıntı olduğunu seçtiğin karakter dizelerinizde görünmüyor. Benim durumumda çok büyük bir tablo ihraç etmek zorunda kaldım ve tellerde görünmeyen özel bir karakter yoktu.

psql -c "COPY (SELECT row_to_json(t) from my_table as t) to STDOUT;" | 
    sed 's/\\"/\"/g' > my_table.json 

Ben boru basitçe \" ile \\" tekrarlarını değiştirir için duyuyorum sed ifadesi:

bu sorunu çözmek için, ben tırnak Çift kaçışa dönmek sed için COPY komutun çıktısını borulu.

+0

Biraz farklı sed tarifi ile başarı elde ettim: Tüm ters eğik çizgi çiftlerini tek ters eğik çizgi ile değiştirin: "sed"/\\\\/\\/g '. –

+0

Postgres'in daha yeni sürümlerinde (9.3'ten beri inanıyorum), COPY deyiminde COPY ifadesine bir filtre de ekleyebilirsiniz (COPY (SELECT row_to_json (t) my_table öğesinden t'ye kadar) TO PROGRAM $$ sed 's/\\\\/\\/g '> my_table.json $$ ' –

İlgili konular