Categories
django GNU/Linux

Upgrading SQLite on CentOS to 3.8.3 or Later

Let me guess you are using django and 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.

However you now have this exception to deal with…

ImproperlyConfigured: SQLite 3.8.3 or later is required (found 3.7.17)

This means you will need to upgrade SQlite as django only supports SQlite 3.8.3 and later.

Unfortunately CentOS 6/7 only has v3.7.17 of SQLite in their repos.

So you need to install v3.8.3 or higher of SQLite from source.

To install from source (I’m not sure how to use the precompiled binaries):

  1. Download the source code from sqlite downloads

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 (read eval print loop) – it is still using the old version:


python
>>> import sqlite3
>>> sqlite3.sqlite_version
'3.7.17'

To fix this you need to recompile python to use the new path to sqlite3.

Recompiling Python to Use the New Sqlite3

When compiling 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: /usr/local/lib

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.
Using 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)"

Sources