【问题标题】:psycopg2 unicodeencodeerror with german umlauts带有德语变音符号的 psycopg2 unicodeencodeerror
【发布时间】:2019-07-26 12:06:08
【问题描述】:

我当前的 python 脚本有问题。

我使用os.walk 扫描预定义目录,返回一个包含找到的所有图像文件的列表。我通过psycopg2 将该列表与postgres 数据库进行比较。

它可以正常工作,直到我到达名称中带有german umlaut 的子目录或文件(äöü),然后它会收到以下错误:

UnicodeEncodeError: 'utf-8' codec can't encode characters in position 146-147: surrogates not allowed

我当前的代码如下:

import psycopg2
import settings
import os


def open_conn():
    conn = psycopg2.connect(
                            user=settings.DB_USER,
                            password=settings.DB_PW,
                            host=settings.DB_IP,
                            port=settings.DB_Port,
                            database=settings.DB_DB
                        )
    return conn


def filterExtensions(file_, extensions_):
    if file_.lower().endswith(extensions_):
        return True
    return False


def getFiles(path_, topdown_=False):
    files_found = []
    for root, dirs, files in os.walk(path_, topdown=topdown_):
        for name in files:
            files_found.append(os.path.join(root, name))
    return files_found


for folders_ in settings.FILE_DIR:
    files_found = getFiles(os.path.join(os.getcwd(), folders_))


conn = open_conn()
cur = conn.cursor()


for file_ in files_found:
    qs = "SELECT * FROM image_meta WHERE sourcefile = '" + file_ + "';"
    cur.execute(qs)
    conn.commit()

当我到达 cur.execute(qs) 时,我得到了错误。

当我硬编码路径仅用于测试时,它可以完美运行。

qs = "SELECT * FROM image_meta WHERE sourcefile = '/src/filecrawler/filecrawler/images/original/Grüner_Testordner/IMG_0004.CR2';"

我正在运行 python3psycopg2 2.8.3

编辑: 在将我的代码更改为 holdenweb 和 frankegoesdown 指出后,我仍然遇到相同的错误。

  File "test.py", line 42, in <module>
    cur.execute(qs, (file_,))
UnicodeEncodeError: 'utf-8' codec can't encode characters in position 101-102: surrogates not allowed

我不知道它是否重要,但文件和文件夹是在 mac 上创建的。

【问题讨论】:

    标签: python python-3.x psycopg2


    【解决方案1】:

    欢迎来到 Stackoverflow。恐怕您构建查询的方法 从不推荐。

    Python 数据库模块允许您使用parameterized queries,其中包含 实际数据值的占位符。然后将值本身提供在 一个元组作为第二个参数传递给游标的 execute 方法。

    psycopg2 使用 pyformat 参数化机制,所以尝试替换 有问题的陈述与

    qs = "SELECT * FROM image_meta WHERE sourcefile = %s"
    cur.execute(qs, (file_,))
    

    这将确保您的 SQL 构造正确。如果您仍然遇到问题,则可能与文件名的编码假设不正确有关。

    【讨论】:

    • 谢谢。我相应地更改了代码,但我仍然得到同样的错误。我编辑了我的问题。
    • 但是错误报告改变了——为什么?在您完全了解发生了什么之前,不要假设您已经找到了问题的原因。添加打印调用可能也是一个好主意,直​​到您发现发生了什么。积极调查,不要坐等答案!
    • 嗯,人们很快就下结论了。错误仍然在 ä 的位置,因为我给 cur.execute 一个参数而不是预先构造的字符串。只要我更改文件夹名称中的 ä 它就可以工作。我已经在我的代码中尝试了打印语句,一切正常。它打印出包含 ä 的路径,没有任何问题。但是一旦它击中cur.execute,它就会失败。
    • 感谢您的意见。我会把这个留给更有能力(和耐心)的回答者。
    • 还是感谢您的初步回答。我相应地更改了我的查询
    【解决方案2】:
    for file_ in files_found:
        qs = "SELECT * FROM image_meta WHERE sourcefile = %s;"
        cur.execute(qs, (file_, ))
        conn.commit()
    

    正如@holdenweb 所说,您可以在本文中看到的所有内容:http://initd.org/psycopg/docs/usage.html#query-parameters

    【讨论】:

    • 谢谢。我相应地更改了代码,但我仍然得到同样的错误。我编辑了我的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-11
    • 1970-01-01
    • 2016-01-21
    • 2013-02-09
    • 1970-01-01
    相关资源
    最近更新 更多