如何从 Python 中的 SQLite 查询获取(扩展)结果/错误代码? 例如:
con = sqlite3.connect("mydb.sqlite")
cur = con.cursor()
sql_query = "INSERT INTO user VALUES(?, ?)"
sql_data = ("John", "MacDonald")
try:
cur.execute(sql_query, sql)
self.con.commit()
except sqlite3.Error as er:
# get the extended result code here
现在假设第一列应该是唯一的,并且第一列中已经有一个带有“John”的数据库条目。这将引发 IntegrityError,但我想知道 SQLite 结果/错误代码,如 http://www.sqlite.org/rescode.html#extrc 中所述。 我想知道,因为我想针对不同的错误采取不同的操作。
有关相关错误的更多信息可以通过以下方式获取:
import sqlite3
import traceback
import sys
con = sqlite3.connect("mydb.sqlite")
cur = con.cursor()
sql_query = "INSERT INTO user VALUES(?, ?)"
sql_data = ("John", "MacDonald")
try:
cur.execute(sql_query, sql_data)
con.commit()
except sqlite3.Error as er:
print('SQLite error: %s' % (' '.join(er.args)))
print("Exception class is: ", er.__class__)
print('SQLite traceback: ')
exc_type, exc_value, exc_tb = sys.exc_info()
print(traceback.format_exception(exc_type, exc_value, exc_tb))
con.close()
目前,您无法通过Python的
sqlite3
模块获取错误代码。根据 https://www.sqlite.org/c3ref/errcode.html,C API 分别通过 sqlite3_errcode
、sqlite3_extended_errcode
和 sqlite3_errmsg
公开基本错误代码、扩展错误代码和错误消息。然而,搜索 CPython 源代码发现:
sqlite3_extended_errcode
甚至从来没有接到电话sqlite3_errmsg
被调用,结果作为异常消息公开sqlite3_errcode
被调用,但结果永远不会直接暴露;它只是用来决定引发哪个异常类虽然您要求的功能很有用(事实上,我现在需要它来进行调试,并且因它的缺失而感到沮丧),但它现在根本不存在。
嗯,这个问题很老了,我认为他们已经暴露了一些错误来捕获它们。如果您只想管理问题中提到的完整性错误,您可以这样做:
import sqlite3
import os, traceback
if os.path.exists("test.db"):
os.remove("test.db")
con = sqlite3.connect('test.db')
cur = con.cursor()
cur.execute("create table lang (name TEXT UNIQUE, first_appeared)")
try:
cur.execute("insert into lang values (?, ?)", ("C", 1972))
cur.execute("insert into lang values (?, ?)", ("C", 1972))
except sqlite3.IntegrityError as e:
print('INTEGRITY ERROR\n')
print(traceback.print_exc())
con.commit()
con.close()
此外,您还可以检查他们在 docs 中发布的这些错误:
exception sqlite3.Warning
# A subclass of Exception.
exception sqlite3.Error
# The base class of the other exceptions in this module. It is a subclass of Exception.
exception sqlite3.DatabaseError
# Exception raised for errors that are related to the database.
exception sqlite3.IntegrityError
# Exception raised when the relational integrity of the database is affected, e.g. a foreign key check fails. It is a subclass of DatabaseError.
exception sqlite3.ProgrammingError
# Exception raised for programming errors, e.g. table not found or already exists, syntax error in the SQL statement, wrong number of parameters specified, etc. It is a subclass of DatabaseError.
exception sqlite3.OperationalError
# Exception raised for errors that are related to the database’s operation and not necessarily under the control of the programmer, e.g. an unexpected disconnect occurs, the data source name is not found, a transaction could not be processed, etc. It is a subclass of DatabaseError.
exception sqlite3.NotSupportedError
# Exception raised in case a method or database API was used which is not supported by the database, e.g. calling the rollback() method on a connection that does not support transaction or has transactions turned off. It is a subclass of DatabaseError.
从 Python 3.11 开始就可以了。
import os
import sqlite3
DB_FILE = "mydb.sqlite"
if os.path.exists(DB_FILE):
os.remove(DB_FILE)
con = sqlite3.connect(DB_FILE)
cur = con.cursor()
cur.execute("CREATE TABLE user (first_name TEXT UNIQUE, las_name TEXT)")
try:
cur.execute("INSERT INTO user VALUES(?, ?)", ("John", "MacDonald"))
cur.execute("INSERT INTO user VALUES(?, ?)", ("John", "MacDonald"))
except sqlite3.IntegrityError as e:
print(e)
print("Error code:", e.sqlite_errorcode)
assert e.sqlite_errorcode == sqlite3.SQLITE_CONSTRAINT_UNIQUE
print("Error name:", e.sqlite_errorname)
con.rollback()
con.close()
会回来
UNIQUE constraint failed: user.first_name
Error code: 2067
Error name: SQLITE_CONSTRAINT_UNIQUE