Python PyODBC 和 SQL Server 编码问题

问题描述 投票:0回答:1

我有一个包含值的 json 文件,其中包含“č”、“ė”等字符。我想将这些值插入 SQL Server 数据库,但我在数据库中看到的值是“Ä”而不是“č”、“ Ä—' 代替 'ė','ÄŒ' 代替 'Č' 等等。我该如何处理这个问题?

我尝试了 StackOverflow 和 pyodbc wiki 上的东西,例如:

self.connection.setdecoding(pyodbc.SQL_CHAR, encoding='utf-8')
self.connection.setdecoding(pyodbc.SQL_WCHAR, encoding='utf-8')
self.connection.setencoding(encoding='utf-8')

(也尝试过 latin1 编码,因为我在某个地方看到它可以提供帮助)。

我尝试将字符集添加到连接字符串:

connection_string = (
    f'DRIVER={{ODBC Driver 18 for SQL Server}};'
    f'SERVER={server};'
    f'DATABASE={database};'
    'Trusted_Connection=yes;'
    'Encrypt=no;'
    'CHARSET=UTF-8;'
)

但没有解决我的问题。

这就是我阅读文件的方式:

def read_values(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        return json.load(file)

这就是我插入数据的方式:

def insert(self, table_name: str, column_values: dict):
    columns = ', '.join(column_values.keys())
    values = ', '.join([f"'{value}'" for value in column_values.values()])

    query = f"INSERT INTO {table_name} ({columns}) VALUES ({values})"
    print(query)

    try:
        cursor = self.connection.cursor()
        cursor.execute(query)
        cursor.execute("SELECT @@IDENTITY AS ID;")
        last_inserted_id = cursor.fetchone()[0]
        self.connection.commit()
        print("Data inserted successfully.")
        return last_inserted_id
    except Exception as e:
        print(f"Error inserting data: {e}")
    finally:
        cursor.close()

print(query)
使用正确的字符打印正确的查询。

如果我用键盘将正确的字符直接写入数据库,一切都会正常。

python sql-server character-encoding pyodbc
1个回答
0
投票

问题 1:不要对 SQL Server 使用
.setencoding()
.setdecoding()

如 SQL Server 的 pyodbc wiki 条目中所述,它们不是必需的。

问题 2:不要使用字符串格式(也称为动态 SQL)将列

values 注入 SQL 语句中。

您遇到的真正问题是您正在构建一个看起来像这样的 INSERT 语句:

print(query) # INSERT INTO so78154305 (firstname) VALUES ('Renée')
SQL Server 使用 

'string'

 表示 varchar,使用 
N'string'
 表示 nvarchar,因此 Unicode 文字应为 
N'Renée'

但这仍然是不好的形式。请改用参数化查询。例如

columns = ', '.join([f"[{key}]" for key in column_values.keys()]) placeholders = ', '.join("?" * len(column_values.values())) query = f"INSERT INTO [{table_name}] ({columns}) VALUES ({placeholders})" print(query) # INSERT INTO [so78154305] ([firstname], [active]) VALUES (?, ?) cursor.execute(query, tuple(column_values.values()))
    
© www.soinside.com 2019 - 2024. All rights reserved.