Upgrading SQLite on CentOS to 3.8.3 or Later in Python
Solving sqlite error in Python Django may have just done an upgrade to Django 2.2.x or 3.x in order to stay up to date and have the latest security updates. This means you will need to upgrade SQLite, as Django only supports SQLite 3.9.0 and later.
Unfortunately CentOS 6/7 only has v3.7.17 of SQLite in their repos.
So you need to install v3.8.3 of SQLite or the latest from source.
To install from source (I'm not sure how to use the precompile binaries):
- Download the source code from sqlite downloads
Latest Version of source Code https://www.sqlite.org/2021/sqlite-autoconf-3360000.tar.gz
cd /opt wget https://www.sqlite.org/2019/sqlite-autoconf-3280000.tar.gz tar -xzf sqlite-autoconf-3280000.tar.gz cd sqlite-autoconf-3280000 ./configure make sudo make install
However this doesn't help us, as from the python repl - it is still using the old version:
python >>> import sqlite3 >>> sqlite3.sqlite_version '3.7.17'
You need to recompile python to use the new path to sqlite3.
Recompiling Python to Use the New Sqlite3
sqlite3 you get some useful info (that we usually skip over):
Libraries have been installed in: /usr/local/lib If you ever happen to want to link against installed libraries in a given directory, LIBDIR, you must either use libtool, and specify the full pathname of the library, or use the '-LLIBDIR' flag during linking and do at least one of the following: - add LIBDIR to the 'LD_LIBRARY_PATH' environment variable during execution - add LIBDIR to the 'LD_RUN_PATH' environment variable during linking - use the '-Wl,-rpath -Wl,LIBDIR' linker flag - have your system administrator add LIBDIR to '/etc/ld.so.conf'
This is exactly what we want to do - we must use the library directory:
Check you sqlite version:
[root@server]# sqlite3 --version 3.31.1 2020-01-27 19:55:54 3bfa9cc97da10598521b342961df8f5f68c7388fa117345eeb516eaa837bb4d6
Then make sure to compile python again using the
LD_RUN_PATH environment variable.
It is better to use this variable over
LD_LIBRARY_PATH- whenever python is run (at runtime) it will look for linked libraries with that path.
What we want is for the libraries to be cooked into python at link time - compile time.
So lets compile python from source which you can get from python.org/downloads:
cd /opt/Python-x.y.z LD_RUN_PATH=/usr/local/lib ./configure LD_RUN_PATH=/usr/local/lib make LD_RUN_PATH=/usr/local/lib make altinstall
Now you should be using the updated version
[root@server Python-3.6.8]# python3 Python 3.6.8 (default, May 8 2020, 11:34:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import sqlite3 >>> sqlite3.sqlite_version '3.31.1'
More information on the dynamic linker at the gcc docs
If you do not use
LD_RUN_PATH, then you have to make sure that the
LD_RUN_PATH environment variable is set to
/usr/local/lib for every user that is going to run python - which can be really annoying to do.
Hopefully your python environment is now using the correct sqlite version.
Checking SQlite3 version quickly
How to quickly check your SQLite version
python3.6 -c "import sqlite3; print(sqlite3.sqlite_version)"