Package: django-informixdb
A database driver for Django to connect to an Informix database via pyodbc.Some limitations:Does not support default valuesInformix automatically creates indexes on foreign keys, but Django attempts to do that
manually; the current implementation here just attempts to catch the error on index
creation. It may unintentionally catch other index creation errors where the index
already exists.Configure local environmentThe following environment variables should exist:INFORMIXDIRThe path to the Informix client install directoryINFORMIXSERVERThe name of the Informix service to which we need to connectINFORMIXSQLHOSTSThe path to thesqlhostsfile that the Informix driver should useLD_LIBRARY_PATHThe path(s) to the various Informix library files: Usually$INFORIMIXDIR/lib:$INFORMIXDIR/lib/cli:$IMFORMIXDIR/lib/esqlDB_LOCALEIn case ofDatabase locale information mismatch.error during connection,
you should specify your database locale, e.g.DB_LOCALE=en_US.8859-15You will also need to add an entry within yoursqlhostsfile for each remote/local Informix
server connection in the following format:<INFORMIX_SERVER_NAME>    onsoctcp     <INFORMIX_HOST_NAME>    <INFORMIX_SERVICE_NAME>For example:dev    onsoctcp    localhost    9088You may alternatively use a symbolic name in that line in place of the port number, typicallysqlexecand
then configure the port number in the/etc/servicesfile:sqlexec    9088/tcpConfigure settings.pyDjango’s settings.py uses the following to connect to an Informix database:'default':{'ENGINE':'django_informixdb','NAME':'myproject','SERVER':'ifxserver','USER':'testuser','PASSWORD':'passw0rd','OPTIONS':{'DRIVER':'/path/to/iclit09b.so'.# Or iclit09b.dylib on macOS'CPTIMEOUT':120,'CONN_TIMEOUT':120,'ISOLATION_LEVEL':'READ_UNCOMMITTED','LOCK_MODE_WAIT':0,'VALIDATE_CONNECTION':True,},'CONNECTION_RETRY':{'MAX_ATTEMPTS':10,},'TEST':{'NAME':'myproject','CREATE_DB':False}}CPTIMEOUTThis will set connection pooling timeout.
Possible values:0 - Turn off connection pooling
nn - timeout set nn secondsCONN_TIMEOUTThis will set timeout for operations on connections (connection, ??closing??, we’re not sure).
Possible values:0 - Default timeout to the database (which could mean no timeout)
nn - timeout set nn secondsISOLATION_LEVELThis will set database isolation level at connection level
Possible values:READ_COMMITED
READ_UNCOMMITTED
SERIALIZABLELOCK_MODE_WAITThis will set database LOCK MODE WAIT at connection level
Application can use this property to override the default server
process for accessing a locked row or table.
The default value is 0 (do not wait for the lock).
Possible values:-1 - WAIT until the lock is released.
0 - DO NOT WAIT, end the operation, and return with error.
nn - WAIT for nn seconds for the lock to be released.VALIDATE_CONNECTIONWhether existing connections should be validated at the start of the request. Defaults toFalse.VALIDATION_INTERVALHow often in seconds to revalidate connections ifVALIDATE_CONNECTIONis enabled. Defaults to300(5 minutes).VALIDATION_QUERYQuery used to validate whether a connection is usable. Defaults to“SELECT 1 FROM sysmaster:sysdual”.CONNECTION_RETRYWhen opening a new connection to the database, automatically retry up toMAX_ATTEMPTStimes
in the case of errors. Only error codes inERRORSwill trigger a retry. The wait time
between retries is calculated using an exponential backoff with jitter formula:random_between(WAIT_MIN, min(WAIT_MAX, WAIT_MULTIPLIER * WAIT_EXP_BASE ** (attempt - 1)))Defaults (wait times are in milliseconds):MAX_ATTEMPTS: 1  # this implies no retries
WAIT_MIN: 0
WAIT_MAX: 1000
WAIT_MULTIPLIER: 25
WAIT_EXP_BASE: 2
ERRORS: ['-908', '-930', '-27001']Each of these settings can be overridden in theCONNECTION_RETRYsection of the database
configuration insettings.py. For example:DATABASES = {
   'default': {
       'ENGINE': 'django_informixdb',
       'CONNECTION_RETRY': {
           'MAX_ATTEMPTS': 10,
           'WAIT_MIN': 0,
           'WAIT_MAX': 500,
       },
       # ...
    },
 }The error codes that are retried by default correspond to the following errors:-908Attempt to connect to database server (servername) failed-930Cannot connect to database server servername-27001Read error occurred during connection attemptThese errors are often seen when the database server is too busy, too many clients are
attempting to connect at the same time or a network firewall has chopped the connection.Using with the Docker Informix Dev DatabaseThe docker image from IBM for the Informix developer database image behaves a little differently compared to other images. As such it needs a little extra handling, and doesn’t seem to work with docker-composeFirstly we need to download and getting it running:$dockerrun-itd--nameiif_developer_edition--privileged-p9088:9088-p9089:9089-p27017:27017\-p27018:27018-p27883:27883-eLICENSE=acceptibmcom/informix-developer-database:latestThis will download the image if it doesn’t exist, and then run it with the nameiif_developer_edition. The first time this run, the image will do a bunch of initial setup stuff. As we used the-doption, it will run in the background as a detached process. So don’t be concerned that you do not see anything in the output.You can stop and restart the container with:$dockerstopiif_developer_edition$dockerstartiif_developer_editionIt seems that the Informix ODBC driver does not currently support creating databases. So we will need to do
that manually, by attaching to the running container$dockerattachiif_developer_editionThis will give you a shell on the running container, and you can therefore use dbaccess to create your database.
You can exit this shell usingCtrl-pCtrl-qwithout shutting down the whole container.This Django database adaptor for Informix requires transaction support to be enabled in our database.
This is not the default within the Informix Developer image.  So you need to enable it on a per database basis:$dockerattachiif_developer_edition$ontape-s-B<DB_NAME>Again, you can detach usingCtrl-pCtrl-q.Finally you need to ensure that our local dev database is included in thesqlhostsfile. e.g.:devonsoctcplocalhost9088You should now be able to point Django to our local test database using the syntax detailed above.Using Django InformixDB with docker-composeIt is possible to use the Informix developer docker image with docker-compose with a little effort.Example docker-compose.ymlversion:'3'services:db:image:ibmcom/informix-developer-databasetty:true# Needed to ensure container doesn't self terminateenvironment:LICENSE:acceptprivileged:trueports:-"9088:9088"-"9089:9089"-"27017:27017"-"27018:27018"-"27883:27883"The key entry in the compose file which is out of the ordinary istty: true. This allocates a (virtual) TTY to the container. The Informix developer database container expects attyand terminates without one when run inside docker-compose.Once it is up and running withdocker-compose upyou can run abashshell on the running container with:dockerexec-itinformix_db_1bashWhereinformix_db_1is the name of the running container. From this shell you can create your DB withdbaccessetc.WarningThis approach still requires the SDK to installed locally and the appropriate environmental variables to be set up. Along with entries insqlhostsand/etc/servicesTesting against an Informix DatabaseDue to a bug in the Informix ODBC driver, it is not currently possible to run Django tests normally. Specifically, it is not possible for Django to create a test database. As such, you will need to do it manually. By default Django will attempt to create a database with a name equal to the default database name with atest_prefix. e.g. if you database name ismy_database, the test database name would betest_my_database.  This can be overridden with theNAMEoption underTEST.To prevent Django from attempting to create a test database, set theCREATE_DBoption
underTESTtoFalse: see ‘Configure settings.py’ above.You can follow the steps above, in the section on using Informix locally with Docker to create a test database. Then when running the test you can tell Django to re-use an existing database, rather than trying to create a new one with the-kparameter:./manage.pytest-kFor django_informixdb DevelopersTo run the django_informixdb test suite, you need to set the INFORMIXDIR environment variable, and the tests
expect an Informix database at host “informix”. Change that host intest/conftest.pyif you need to.
Then run the test suite with:toxThis will run the tests under Django 3 and 4.Docker based testingIf you don’t want to install the Informix libraries and multiple versions of Python locally, then you can test within
Docker containers.Try using the helper scripttest-in-docker.sh, or inspect the script and adapt for your own purposes.Requirements: Docker 19.03.2 or newer and Docker Compose 1.24.1 or newer.Release HistoryVersion 1.11.4Update pyproject.toml / setup.cfg and update docker tests to use Rocky9 instead of Centos7Version 1.11.3Switch from setup.py to pyproject.toml / setup.cfgVersion 1.11.2Begin support for Python 3.10Version 1.11.1Convert from TravisCI to GitHub ActionsVersion 1.11.0Begin support for Django 4.xEnd support for Django 2.xEnd support for Python 3.6Version 1.10.1Fix forhttps://github.com/reecetech/django_informixdb/issues/31Version 1.10.0Begin support for Django 3.xBegin support for Python 3.9Version 1.9.1Begin support for Python 3.7 and 3.8End support for Django 1.x and Python 3.5Version 1.9.0Enable setting a validation interval.Version 1.8.0Enable validating connections at start of request.Version 1.7.0Add CONN_TIMEOUT setting.Version 1.5.0Enable retrying if get connection fails.Version 1.3.3Compability fix for Django 2+ to remove old “context” argument from
custom fieldsVersion 1.3.0Addressing deprecation warning for conversion functions in Django 2+Detect incorrect INFORMIXSQLHOSTS setting earlier for better error messageVersion 1.2.0Fix bug in DecimalField handling under Django 2+Version 1.1.0Added LOCK_MODE_WAIT optionVersion 1.0.0Initial public release