sql >> Databáze >  >> RDS >> PostgreSQL

Python + PostgreSQL + podivné ascii =chyba kódování UTF8

Otázka začíná mylným předpokladem:

ASCII znaky jsou v rozsahu "\x00" až "\x7F" včetně.

Dříve přijatá nyní smazaná odpověď fungovala na základě dvou hrubých nedorozumění (1) že locale ==kódování (2) že kódování latin1 mapuje "\x80" na znak Euro.

Ve skutečnosti všechna kódování ISO-8859-x mapují "\x80" na U+0080, což je jeden z řídicích znaků C1, nikoli znak Euro. Pouze 3 z těchto kódování (x v (7, 15, 16)) poskytují znak Euro, jako "\xA4". Viz tento článek na Wikipedii .

Musíte to vědět v jakém kódování jsou vaše data. Na jakém počítači byla vytvořena? Jak? Národní prostředí, ve kterém byl vytvořen (ne nutně vaše), vám může napovědět.

Všimněte si, že "Moje data jsou zakódována v latin1" je tam nahoře s "Šek je v poště" a "Samozřejmě, že tě ráno budu milovat". Vaše data jsou pravděpodobně zakódována v jednom z kódování cp125x na platformách Windows. Všimněte si, že všechny kromě cp1251 (azbuka Windows) mapují "\x80" na znak eura:

>>> ['\x80'.decode('cp125' + str(x), 'replace') for x in range(9)]
[u'\u20ac', u'\u0402', u'\u20ac', u'\u20ac', u'\u20ac', u'\u20ac', u'\u20ac', u'\u20ac', u'\u20ac']

Aktualizovat v reakci na komentář OP

To je trochu matoucí:Nejprve řeknete

Ale později řeknete

Prosím o vysvětlení.

Výběr vhodného kódování cp125x:Kde (geografické umístění) byl soubor vytvořen? V jakém jazyce (jazycích) je text napsán? Nějaké jiné znaky než předpokládané euro s hodnotami> "\x7f"? Pokud ano, které a v jakém kontextu se používají?

Aktualizace 2 Pokud "nevíte, jak je program napsán", nemůžeme si ani vy ani my vytvořit názor na to, zda vždy používá "\x80" pro znak eura. I když by to jinak bylo monumentální hloupostí, nelze to vyloučit.

Pokud je text napsán v angličtině a/nebo je napsán v USA a/nebo je napsán na platformě Windows, pak je přiměřeně jisté, že cp1252 je správná cesta ... dokud nezískáte důkaz o opaku, v takovém případě budete muset uhodnout kódování sami nebo odpovědět na otázky (v jakém jazyce, v jaké lokalitě).




  1. SQLite JSON_PATCH()

  2. Přístup odepřen uživateli ''@'localhost' (pomocí hesla:NE)

  3. Předávání hodnot do vkládacího dotazu s výběrovým dotazem

  4. Ekvivalent Oracle ISNULL().