[英]Encoding calling from pyodbc to a MS SQL Server
我使用pyodbc模塊通過SQL Alchemy連接到MS SQL服務器。 一切似乎工作正常,直到我開始遇到編碼問題。 一些非ascii字符被替換為'?'
DB有一個排序規則'Latin1_General_CI_AS'(我還檢查了特定的字段,它們保持相同的排序規則)。 我開始在create_engine
的調用中選擇編碼'latin1',這似乎適用於西歐字符(如法語或西班牙語, é
字符),但不適用於復活節歐洲字符。 具體來說,我的角色ć
有問題
我一直在嘗試選擇Python文檔中所述的其他編碼,特別是微軟的cp1250
,如cp1250
和cp1252
,但我仍面臨同樣的問題。
有誰知道如何解決這些差異? 排序規則'Latin1_General_CI_AS'是否與Python編碼具有等價性?
我當前連接的代碼如下
for sqlalchemy import *
def connect():
return pyodbc.connect('DSN=database;UID=uid;PWD=password')
engine = create_engine('mssql://', creator=connect, encoding='latin1')
connection = engine.connect()
澄清和評論:
ć
儲存在哪里? 也許我沒有正確理解整理。 latin1
更多的編碼, cp1250
和cp1252
(顯然是'Latin1_General_CI_AS'上使用的cp1250
,根據msdn) 更新:
好的,按照這些步驟,我得到數據庫使用的編碼似乎是cp1252: http ://bytes.com/topic/sql-server/answers/142972-characters-encoding無論如何,這似乎是一個不好的假設如答案所反映的那樣。
UPDATE2:無論如何,在正確配置odbc驅動程序之后,我不需要在Python代碼上指定編碼。
您應該停止使用代碼頁並切換到Unicode。 這是解決這類問題的唯一方法。
原評論變成了答案:
cp1250和cp1252不是“latin1編碼”。 排序規則不是編碼。 重新評論:誰說“服務器是用latin1編碼的”? 如果服務器期望所有輸入/輸出都以latin1編碼(我懷疑),那么你很難將一些東歐字符放入你的數據庫(俄語,中文,希臘語等)。
更新 :
你需要比整理更深入。 “”msdn.microsoft.com/en-us/library/ms174596(v=SQL.90).aspx建議,對於Latin1_General_CI_AS,使用的編碼是cp1252“”“是codswallop。 該表為每個語言環境提供LCID(語言環境ID), 默認排序規則和代碼頁。 是的,排序規則“Latin1_General_CI_AS”與多個語言環境的cp1252代碼頁一起列出。 對於兩個語言環境(亞美尼亞語和格魯吉亞語),它與“Unicode”代碼頁(!!!)一起列出。
很簡單,您需要找出數據庫正在使用的代碼頁 。
嘗試從數據庫中提取數據而根本不指定編碼。 不要打擾你猜測你的控制台可能正在使用的任何編碼 - 這只會增加另一個混亂的來源。 而是使用print repr(data)
。 在這里報告您從repr()獲得的非拉丁文字符。
嘗試使用pyodbc.connect()參數convert_unicode=True
連接到db,例如。 來自sqlalchemy:
engine = create_engine('mssql://yourdb', connect_args={'convert_unicode': True})
這應該確保您獲得的所有結果(而不僅僅是來自nvarchar
等的結果......)是unicode,從db中使用的任何編碼中正確轉換。
至於寫入數據庫,只需使用unicode。 如果我沒有弄錯(稍后會檢查),pyodbc將確保它也會正確寫入數據庫。
(當然,如果db使用的編碼不支持您要編寫的字符,您仍會遇到錯誤:如果您希望列支持任何類型的字符,則還必須在db上使用unicode列)
OK,每http://msdn.microsoft.com/en-us/library/ms174596(v=SQL.90).aspx的編碼Latin1_General_CI_AS
是最有可能cp1252
。 所以,你必須使用encoding='cp1252'
。 但是這只能解決問題的一半,因為你必須以某種方式輸出值來查看字符是否存在。 因此,如果您有從數據庫中提取的some_db_value
,則必須使用some_db_value.encode('proper-output-encoding')
來使其正確。 proper-output-encoding
取決於你如何輸出:在控制台上,它是控制台編碼,可以是'cp1252','cp437','cp850'(在Windows上)。 在網絡上,它是網絡服務器的編碼,希望'utf-8'。
編輯:請閱讀約翰·馬金的回答 ,因為它是不明確的“CP1252”是否是正確的數據庫編碼
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.