CockroachDB backend for Django
Prerequisites
You must install either:
-
psycopg2, which has some prerequisites of its own.
The binary package is a practical choice for development and testing but in production it is advised to use the package built from sources.
Install and usage
Use the version of django-cockroachdb that corresponds to your version of Django. For example, to get the latest compatible release for Django 3.0.x:
pip install django-cockroachdb==3.0.*
The minor release number of Django doesn't correspond to the minor release number of django-cockroachdb. Use the latest minor release of each.
Configure the Django DATABASES setting similar to this:
DATABASES = {
'default': {
'ENGINE': 'django_cockroachdb',
'NAME': 'django',
'USER': 'root',
'PASSWORD': '',
'HOST': 'localhost',
'PORT': '26257',
# If connecting with SSL, remove the PASSWORD entry above and include
# the section below, replacing the file paths as appropriate.
'OPTIONS': {
'sslmode': 'require',
'sslrootcert': '/certs/ca.crt',
'sslcert': '/certs/client.myprojectuser.crt',
'sslkey': '/certs/client.myprojectuser.key',
},
},
}Notes on Django fields
-
CharField'smax_lengthis ignored. It uses the same storage asTextFieldsoCharFieldis introspected byinspectdbasTextField. -
IntegerFielduses the same storage asBigIntegerFieldsoIntegerFieldis introspected byinspectdbasBigIntegerField. -
AutoFieldandBigAutoFieldare both stored as integer (64-bit) withDEFAULT unique_rowid().
Notes on Django QuerySets
-
QuerySet.explain()acceptsverbose,types,opt,vec, anddistsqloptions which correspond to CockroachDB's parameters. For example:>>> Choice.objects.explain(opt=True, verbose=True) 'scan polls_choice\n ├── columns: id:1 question_id:4 choice_text:2 votes:3\n ├── stats: [rows=1]\n ├── cost: 1.1\n ├── key: (1)\n ├── fd: (1)-->(2-4)\n └── prune: (1-4)'
FAQ
Why do I get the error psycopg2.errors.InvalidName: no database specified?
You may need to create the database.
You can use cockroach sql --insecure on the command line to get a SQL prompt.
Known issues and limitations (as of CockroachDB 20.1.3)
-
CockroachDB can't disable constraint checking, which means certain things in Django like forward references in fixtures aren't supported.
-
Migrations have some limitations. CockroachDB doesn't support:
- changing column type
- dropping or changing a table's primary key
-
Known Bugs:
-
Unsupported queries:
- Mixed type addition in SELECT:
unsupported binary operator: <int> + <float> - UPDATE float column with integer column:
value type int doesn't match type FLOAT8 of column <name> - Division that yields a different type:
unsupported binary operator: <int> / <int> (desired <int>) - The power() database function doesn't accept negative exponents:
power(): integer out of range - The
StdDevandVarianceaggregates aren't supported. - sum() doesn't support arguments of different types:
sum(): unsupported binary operator: <float> + <int> - greatest() doesn't support arguments of different types:
greatest(): expected <arg> to be of type <type>, found type <other type> SmallAutoFieldgenerates values that are too large for any corresponding foreign keys.- The
SHA224andSHA384database functions aren't supported.
- Mixed type addition in SELECT:
Additional issues and limitations in CockroachDB 19.2.x (as of 19.2.8)
-
Savepoints aren't supported. This means a few things:
- Django's transaction.atomic() can't be nested.
- Django's
TestCaseworks likeTransactionTestCase. That is, transactions aren't used to speed up the former.
-
Known Bugs:
- The extract() function doesn't respect the time zone.
- Interval math across daylight saving time is incorrect.
date_trunc('week', <value>)truncates to midnight Sunday rather than Monday- date_trunc() results are incorrectly localized.
- cast() timestamptz to time doesn't respect the time zone.
- Interval math may be incorrect on date columns.
-
Unsupported queries:
- extract() doesn't support interval columns (DurationField):
unknown signature: extract(string, interval) - The log() function doesn't support custom bases:
unknown signature: extract(string, interval) - timezone() doesn't support UTC offsets:
timezone(): unknown time zone UTC...
- extract() doesn't support interval columns (DurationField):

