SQLite创建数据库/文件而不是打开现有的。

huangapple go评论65阅读模式
英文:

SQLite creates DB/file instead of opening the existing one

问题

I'm only providing translations for the non-code parts of your text:

I am trying to open an SQLite database in python, using the sqlite shared library (libsqlite3.0.dylib on macOS). (I use this library instead of the sqlite3 module, because I need to use the sqlite3_update_hook function, which is not exposed in the python module.)

The organization tree is the following:

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

The file called "imdb-tiny.db" is an SQLite database.
The file CONST.py only contains constants for other scripts.

I am trying to open this database from the python script, using the following code:

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__":

    # Pointer to the DB (more precisely, to an object representing it)
    db = c_void_p()
    # Connection to the SQLite database
    return_number: int = SQLITE3.sqlite3_open(f"{DATA_PATH}imdb-tiny.db", byref(db))
    if return_number != 0:
        # Error opening the DB
        print(f"Failed to open the DB: error {return_number}.", file=stderr)
        print("Error documentation: https://www.sqlite.org/capi3ref.html#SQLITE_ABORT", file=stderr)
        exit(-1)

    # Execute queries on the SQLite database
    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)

The scripts run without any error, but they do not behave as expected. They create a new file/database, called with the first letter of the database name (here, it would be "D" as it is the first character of the string "DATA/imdb-tiny.db"). The location of the created file depends on whether I'm executing from the VSCode extension (MyProject folder) or a terminal (the same location as the terminal). Any idea on why this is happening and how to fix it?

英文:

I am trying to open an SQLite database in python, using the sqlite shared library (libsqlite3.0.dylib on macOS). (I use this library instead of the sqlite3 module, because I need to use the sqlite3_update_hook function, which is not exposed in the python module.)

The organization tree is the following:

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

The file called "imdb-tiny.db" is an SQLite database.
The file CONST.py only contains constants for other scripts.

I am trying to open this database from the python script, using the following code:

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)

The scripts runs without any error, but it does not behave as expected. It creates a new file/database, called with the first letter of the database name (here, it would be "D" as it is the first char of the string "DATA/imdb-tiny.db"). The location of the created file depends on weather I'm executing from VSCode extension (MyProject folder), or a terminal (same location as the terminal). Any idea on why this is happening and how to fix it ?

答案1

得分: 2

代码部分不翻译:

问题在于您没有将字符串编码为utf-8字节列表以供sqlite3_open函数调用。 D 是字符串的第一个字符。

通过显式将字符串编码为字节列表,您将能够打开正确的文件:

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

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

英文:

The problem here is that you don't encode the string into a list of utf-8 bytes for the sqlite3_open function call. The D is the first character of the string.

By explicitly encoding the string into a byte list, you'll be able to open the correct file:

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

The underlying problem is that python has no hints as to the data types that are passed as parameters to the function, but regardless, you need to ensure that the parameters are binary encoded in the correct format for use by the function.

huangapple
  • 本文由 发表于 2023年4月11日 04:18:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/75980410.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定