我对数据库表的列有很多不同的约束。插入数据库的数据通常包含数字数组(在这些数字上设置了约束),例如(DDL的一部分):
CREATE TABLE "Object" (
id INTEGER NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY(id) REFERENCES "Generic" (id) // Inheritance
);
CREATE TABLE "ObjectData" (
id INTEGER NOT NULL,
x FLOAT NOT NULL,
y FLOAT NOT NULL,
d FLOAT NOT NULL,
a FLOAT NOT NULL,
e FLOAT NOT NULL,
object_id INTEGER NOT NULL,
PRIMARY KEY (id),
CONSTRAINT "duplicate x, y values" UNIQUE (x, y, object_id),
CONSTRAINT "x must be >= -1.0" CHECK (x >= 0.0),
CONSTRAINT "x must be <= 1.0" CHECK (x <= 1.0),
CONSTRAINT "y must be >= -1.0" CHECK (y >= -1.0),
CONSTRAINT "y must be <= 1.0" CHECK (y <= 1.0),
CONSTRAINT "d must be >= -1.0" CHECK (d >= 0.0),
CONSTRAINT "d must be <= 1.0" CHECK (d <= 1.0),
CONSTRAINT "a must be >= -270.0" CHECK (a >= -270.0),
CONSTRAINT "a must be <= 270.0" CHECK (a <= 270.0),
CONSTRAINT "e must be >= -1.0" CHECK (e >= -1.0),
CONSTRAINT "e must be <= 1.0" CHECK (e <= 1.0),
FOREIGN KEY(object_id) REFERENCES "Object" (id)
);
插入数据如下所示(经过解析以插入到DB中的输入文本文件的一部分):
DATA:
-1.0 -1.0 1.0 242.0 0.0
-1.0 -2.0 1.0 124.0 0.0
-1.0 -1.0 1.0 109.0 0.0
...........................
-1.0 -1.0 1.0 242.0 0.0
-1.0 -2.0 1.0 124.0 0.0
-1.0 -1.0 1.0 109.0 0.0
因此,如果这些值中的任何一个都违反约束之一,并且没有消息显示,则很难确定哪个值是错误的。为此,给出了约束的描述性名称。通过SQLAlchemy ORM与SQLite3数据库一起使用,并在发生sqlalchemy.exc.IntegretyError时,该库完全切断了违反约束的名称。
从[版本3.3.2] [1]开始,在SQLite3的IntegrityError异常中出现约束名称的情况下进行谷歌搜索。这显示了Python REPL中的简短测试:
>>> import sqlite3
>>> conn = sqlite3.connect('test/test.db')
>>> c = conn.cursor()
>>> c.execute("""INSERT INTO "ObjectData" (x, y, d, a, e, object_id) VALUES (?, ?, ?, ?, ?, ?)""", (-2.0, -1.0, 1.0, 242.0, 0.0, 1))
Traceback (most recent call last):
File "<input>", line 1, in <module>
IntegrityError: CHECK constraint failed: x must be >= -1.0
但是,当我尝试使用SQLAlchemy插入数据时,只会收到一条消息,该消息无法描述发生了什么错误。这是dir(error)的结果:
detail = []
params = (-2.0, -1.0, 1.0, 242.0, 0.0, 1)
statement = INSERT INTO "ObjectData" (x, y, d, a, e, object_id) VALUES (?, ?, ?, ?, ?, ?)
instance = <bound method type.instance of <class 'sqlalchemy.exc.IntegrityError'>>
args = ('(IntegrityError) constraint failed',)
orig = constraint failed
orig.message = constraint failed
因此,问题是否有任何方法可以强制SQLAlchemy返回违反约束的名称,因为它大大简化了代码并允许向用户显示有关错误的信息?还是可能存在其他方式?
最佳答案
我发现SQLAlchemy库使用有问题。当我在调试模式下运行软件并在引发IntegrityError异常(在SQLAlchemy库的DBAPIError.instance方法中设置了断点)时中断时,我意识到原来的错误类型是'pysqlite2._sqlite.Error'类而不是sqlite3。看来在我的Python环境中已经在站点包库pysqlite2中安装了sqlsql3,但这与sqlite3不同。我尝试使用一种简单的解决方法:从站点程序包中删除pysqlite2目录。在该原始异常类型之后,成为类'sqlite3.Error'和orig.message包含在异常中,正是我所期望的。因此,很明显,SQLAlchemy默认情况下使用pysqlite2库,而不是内置的sqlite3库。
关于python - SQLAlchemy IntegrityError违反约束名称,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22694371/