This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Traceback message not returning SQLite check constraint details
Type: enhancement Stage: resolved
Components: Extension Modules Versions: Python 3.4
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: chris.jerdonek, ghaering, jftuga, ned.deily, r.david.murray
Priority: normal Keywords:

Created on 2012-08-21 14:36 by jftuga, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (13)
msg168777 - (view) Author: John Taylor (jftuga) * Date: 2012-08-21 14:36
According to:
http://www.sqlite.org/releaselog/3_7_12.html

SQLite has the ability to, "Report the name of specific CHECK constraints that fail."

CPython 3.3.0b2 which uses SQLite version 3.7.12 does not report which constraint failed.
--
import platform, sqlite3

print("Platform : %s %s" % (platform.python_implementation(),platform.python_version()))
print("SQLite   : %s" % (sqlite3.sqlite_version))
print()

tbl="""\
create table test1 (
        db_insert_date       timestamp,
        check( cast(substr(db_insert_date,1,4) as integer) >= 2000 and cast(substr(db_insert_date,1,4) as integer) <= 2025),
        check( cast(substr(db_insert_date,6,2) as integer) >= 1    and cast(substr(db_insert_date,6,2) as integer) <= 12),
        check( cast(substr(db_insert_date,9,2) as integer) >= 1    and cast(substr(db_insert_date,9,2) as integer) <= 31)
)
"""

conn = sqlite3.connect(":memory:")
c = conn.cursor()
c.execute(tbl)

query = "insert into test1 values( ? )"
c.execute(query, ("2012-08-20", ) )
conn.commit() # this works

c.execute(query, ("2012-18-20", ) )
conn.commit() # returns: sqlite3.IntegrityError: constraint failed (but which constraint?)

"""
Traceback (most recent call last):
  File "C:bug.py", line 34, in <module>
    c.execute(query, ("2012-18-20", ) )
sqlite3.IntegrityError: constraint failed
"""
msg168778 - (view) Author: John Taylor (jftuga) * Date: 2012-08-21 14:41
When I run this under Windows 7:

Platform : CPython 3.3.0b2
SQLite   : 3.7.12

Traceback (most recent call last):
  File "C:bug.py", line 34, in <module>
    c.execute(query, ("2012-18-20", ) )
sqlite3.IntegrityError: constraint failed
msg168783 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2012-08-21 14:55
This is a new feature (ie: adding support for a new feature of sqlite).

Would you like to propose a patch?
msg168785 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2012-08-21 14:59
Having said this is a feature, since it would only affect the error message, I'm actually open to it as a bug fix.  It won't make it into 3.3.0 even if someone proposes a patch, though, given that we are so late in the release process.
msg168788 - (view) Author: John Taylor (jftuga) * Date: 2012-08-21 15:43
I believe patching Python is beyond my programming capability.  I would be very interested in seeing this in 3.3.1.  How else could I assist in making this happen? Thanks!
msg168791 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2012-08-21 16:08
Well, it would be patching the sqlite extension module.  Not that that is much different :)

Hopefully the current sqlite extension maintainer will think this is worthwhile doing.  Short of waiting for that, you could perhaps ask on the python-list email list to see if there is anyone with the requisite skill set interested in contributing a patch.  I will mention it on the core-mentorship mailing list, and perhaps someone there will decided to pick it up (there's a pretty decent chance of that, I think).
msg168794 - (view) Author: Chris Jerdonek (chris.jerdonek) * (Python committer) Date: 2012-08-21 16:53
I would be happy to take a look at this and propose a patch.
msg168795 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2012-08-21 18:08
Keep in mind that Python itself does not release with nor mandate a specific version of sqlite3.  When building CPython yourself, it will use what version is found on your system.  Distributors of built Pythons, including the python.org Windows and OS X installers, may supply a local version or, in some cases, may link dynamically with an operating system supplied version.  So any changes to Python's sqlite3 module and support extension module have to continue to check at either build or run time whether version-specific features are available.
msg168801 - (view) Author: Chris Jerdonek (chris.jerdonek) * (Python committer) Date: 2012-08-21 20:29
I haven't been able to test this via Python because my system sqlite3 version isn't new enough.  But I was able to test this against sqlite3 directly.  I suspect there may be no issue.

John, have you tried naming your constraint?

http://www.sqlite.org/syntaxdiagrams.html#column-constraint

Specifically, if I try your example in sqlite3 3.7.13 (from the command-line, independent of Python), I get the generic error message:

"Error: constraint failed"

But if I add "CONSTRAINT name" to your test case SQL, e.g.

create table test1 (
        db_insert_date       timestamp,
        CONSTRAINT test_constraint1
        check(cast(substr(db_insert_date,1,4) as integer) <= 2025),
        CONSTRAINT test_constraint2
        check(cast(substr(db_insert_date,6,2) as integer) <= 12)
);

I get the error message "Error: constraint test_constraint2 failed".

I suspect things will work fine in Python because the Python code seems simply to use whatever error message sqlite3 provides it:

case SQLITE_CONSTRAINT:
case SQLITE_MISMATCH:
    PyErr_SetString(pysqlite_IntegrityError, sqlite3_errmsg(db));
    break;

(from http://hg.python.org/cpython/file/ca54c27a9045/Modules/_sqlite/util.c#l92 )
msg168802 - (view) Author: John Taylor (jftuga) * Date: 2012-08-21 20:54
Chris,

I will try naming the constraints and will then follow-up.
msg168817 - (view) Author: Chris Jerdonek (chris.jerdonek) * (Python committer) Date: 2012-08-21 22:37
> When building CPython yourself, it will use what version is found on your system.

Ned, this is somewhat off-topic to the issue, but do you know of any ways to tell CPython to use a particular version of sqlite3 at compile time if a system has different versions installed at different locations?  Or perhaps by putting the SQLite source code at an appropriate location in the Python source hierarchy (e.g. using the SQLite amalgamation files: http://www.sqlite.org/download.html )
msg168821 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2012-08-21 23:22
The magic for building the standard library's dynamically loaded extensions is in the top-level setup.py.  It uses Distutils to do the work with a lot of hacking around in setup.py.  Without modifying setup.py, it can be a little tricky to override the search order if you are trying to substitute a library that already exists in one of the normal system locations, particularly if you only want to override for that particular library.  Perhaps the easiest and surest approach is to build and install the library (in this case libsqlite3) into a unique install root and then include the paths to the include and lib directories in the ./configure command for Python, so something like:

   ./configure [other options] LDFLAGS='-L /path/to/sqlite3/lib ' CPPFLAGS='-I /path/to/sqlite3/include '
msg168824 - (view) Author: John Taylor (jftuga) * Date: 2012-08-21 23:42
Please close this ticket. This is not a bug.

As per cjerdonek's suggestion, defining a constraint as follows:

constraint my_name check (...)

returns the actual name of the constraint, when it fails:

sqlite3.IntegrityError: constraint my_name failed
History
Date User Action Args
2022-04-11 14:57:35adminsetgithub: 59959
2012-08-21 23:47:08chris.jerdoneksetresolution: works for me -> not a bug
stage: needs patch -> resolved
2012-08-21 23:42:46jftugasetstatus: open -> closed
resolution: works for me
messages: + msg168824
2012-08-21 23:22:11ned.deilysetmessages: + msg168821
2012-08-21 22:37:56chris.jerdoneksetmessages: + msg168817
2012-08-21 20:54:53jftugasetmessages: + msg168802
2012-08-21 20:29:24chris.jerdoneksetmessages: + msg168801
2012-08-21 18:08:24ned.deilysetnosy: + ned.deily
messages: + msg168795
2012-08-21 16:53:18chris.jerdoneksetnosy: + chris.jerdonek
messages: + msg168794
2012-08-21 16:08:48r.david.murraysetmessages: + msg168791
2012-08-21 15:43:35jftugasetmessages: + msg168788
2012-08-21 14:59:12r.david.murraysetmessages: + msg168785
2012-08-21 14:55:51r.david.murraysetversions: + Python 3.4, - Python 3.3
nosy: + r.david.murray

messages: + msg168783

type: behavior -> enhancement
stage: needs patch
2012-08-21 14:41:01jftugasetmessages: + msg168778
2012-08-21 14:36:26jftugacreate