簡體   English   中英

編碼從pyodbc到MS SQL Server的調用

[英]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 ,如cp1250cp1252 ,但我仍面臨同樣的問題。

有誰知道如何解決這些差異? 排序規則'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()

澄清和評論:

  • 從數據庫中檢索信息時會出現此問題。 我不需要存儲任何東西。
  • 在開始時我沒有指定編碼,結果是,每當在DB上遇到非ascii字符時,pyodbc就會引發UnicodeDecodeError。 我更正了使用'latin1'作為編碼,但這並沒有解決所有字符的問題。
  • 我承認服務器不在latin1上,評論不正確。 我一直都檢查數據庫整理和特定的字段排序規則,似乎是所有“Latin1_General_CI_AS”,那么,如何能ć儲存在哪里? 也許我沒有正確理解整理。
  • 我糾正了一個問題,具體來說,我嘗試了比latin1更多的編碼, cp1250cp1252 (顯然是'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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM