SQLite创建DB/file而不是打开现有的DB/file

toe95027  于 2023-04-21  发布在  SQLite
关注(0)|答案(1)|浏览(225)

我正在尝试使用sqlite共享库(macOS上的libsqlite3.0.dylib)在python中打开SQLite数据库。(我使用此库而不是sqlite3模块,因为我需要使用sqlite3_update_hook函数,该函数在python模块中未公开。)
组织树如下所示:

MyProject/
    SRC/
        - ProductionSQLite.py
        - CONST.py
        DATA/
            - imdb-tiny.db 
            - Some bigger .db files

名为“imdb-tiny.db”的文件是一个SQLite数据库。文件CONST.py只包含其他脚本的常量。
我正在尝试从Python脚本打开这个数据库,使用以下代码:

from ctypes import CDLL, byref
from sys import stderr

DATA_PATH = "DATA/"
DLL_NAME = "libsqlite3.0.dylib" # {"Linux": "libsqlite3.so", "MacOS": "libsqlite3.0.dylib", "Windows": "winsqlite3.dll"}

SQLITE3 = CDLL(DLL_NAME) # Load sqlite3 shared library

if __name__=="__main__":

    # Pointeur vers la DB (plus précisément, vers un objet qui la représente)
    db = c_void_p()
    # Liaison avec la base SQLite
    return_number:int = SQLITE3.sqlite3_open(f"{DATA_PATH}imdb-tiny.db", byref(db))
    if return_number != 0:
        # Erreur à l'ouverture de la DB
        print(f"Echec de l'ouverture de la DB: erreur {return_number}.", file=stderr)
        print(f"Documentation des erreurs: https://www.sqlite.org/capi3ref.html#SQLITE_ABORT", file=stderr)
        exit(-1)

    # Exécution de requêtes sur la base SQLite
    query = b'CREATE TABLE foo (id INT, name VARCHAR(255))'
    err = c_char_p() # Create a variable to hold error messages
    SQLITE3.sqlite3_exec(db, query, None, None, byref(err))
    if err: print(err.value, file=stderr)

脚本运行时没有任何错误,但它的行为并不符合预期。它创建了一个新的文件/数据库,用数据库名称的第一个字母调用(这里,它将是“D”,因为它是字符串“DATA/imdb-tiny.db”的第一个字符)。(MyProject文件夹),或终端(与终端相同的位置)。任何关于为什么会发生这种情况以及如何修复它的想法?

sd2nnvve

sd2nnvve1#

这里的问题是,在sqlite3_open函数调用中,您没有将字符串编码为utf-8字节的列表。D是字符串的第一个字符。
通过将字符串显式编码到字节列表中,您将能够打开正确的文件:

SQLITE3.sqlite3_open(f"{DATA_PATH}imdb-tiny.db".encode('utf-8'), byref(db))

潜在的问题是,python没有关于作为参数传递给函数的数据类型的提示,但无论如何,您需要确保参数以正确的格式进行二进制编码以供函数使用。

相关问题