2019-06-09 08:56:37 +08:00
|
|
|
import operator
|
|
|
|
|
|
|
|
from django.db import transaction
|
2015-01-13 04:20:40 +08:00
|
|
|
from django.db.backends.base.features import BaseDatabaseFeatures
|
2019-06-09 08:56:37 +08:00
|
|
|
from django.db.utils import OperationalError
|
|
|
|
from django.utils.functional import cached_property
|
2015-01-13 04:20:40 +08:00
|
|
|
|
2018-10-25 19:22:40 +08:00
|
|
|
from .base import Database
|
|
|
|
|
2015-01-13 04:20:40 +08:00
|
|
|
|
|
|
|
class DatabaseFeatures(BaseDatabaseFeatures):
|
2018-07-21 02:57:17 +08:00
|
|
|
# SQLite can read from a cursor since SQLite 3.6.5, subject to the caveat
|
|
|
|
# that statements within a connection aren't isolated from each other. See
|
|
|
|
# https://sqlite.org/isolation.html.
|
|
|
|
can_use_chunked_reads = True
|
2015-01-13 04:20:40 +08:00
|
|
|
test_db_allows_multiple_connections = False
|
|
|
|
supports_unspecified_pk = True
|
|
|
|
supports_timezones = False
|
2017-03-25 01:37:03 +08:00
|
|
|
max_query_params = 999
|
2015-01-13 04:20:40 +08:00
|
|
|
supports_mixed_date_datetime_comparisons = False
|
|
|
|
supports_transactions = True
|
|
|
|
atomic_transactions = False
|
|
|
|
can_rollback_ddl = True
|
2018-12-22 07:06:16 +08:00
|
|
|
supports_atomic_references_rename = Database.sqlite_version_info >= (3, 26, 0)
|
2019-01-19 12:17:26 +08:00
|
|
|
can_create_inline_fk = False
|
2015-01-13 04:20:40 +08:00
|
|
|
supports_paramstyle_pyformat = False
|
2015-09-06 17:12:08 +08:00
|
|
|
can_clone_databases = True
|
2016-01-20 09:43:41 +08:00
|
|
|
supports_temporal_subtraction = True
|
2016-11-29 02:29:21 +08:00
|
|
|
ignores_table_name_case = True
|
2017-07-18 03:12:27 +08:00
|
|
|
supports_cast_with_precision = False
|
2018-09-18 19:59:10 +08:00
|
|
|
time_cast_precision = 3
|
2017-10-03 22:42:18 +08:00
|
|
|
can_release_savepoints = True
|
2018-10-25 19:22:40 +08:00
|
|
|
# Is "ALTER TABLE ... RENAME COLUMN" supported?
|
|
|
|
can_alter_table_rename_column = Database.sqlite_version_info >= (3, 25, 0)
|
2018-12-03 06:17:32 +08:00
|
|
|
supports_parentheses_in_compound = False
|
2018-12-14 12:36:02 +08:00
|
|
|
# Deferred constraint checks can be emulated on SQLite < 3.20 but not in a
|
|
|
|
# reasonably performant way.
|
2018-12-22 07:26:30 +08:00
|
|
|
supports_pragma_foreign_key_check = Database.sqlite_version_info >= (3, 20, 0)
|
|
|
|
can_defer_constraint_checks = supports_pragma_foreign_key_check
|
2018-12-27 00:20:11 +08:00
|
|
|
supports_functions_in_partial_indexes = Database.sqlite_version_info >= (3, 15, 0)
|
2019-01-16 11:39:05 +08:00
|
|
|
supports_over_clause = Database.sqlite_version_info >= (3, 25, 0)
|
2019-10-09 19:07:50 +08:00
|
|
|
supports_frame_range_fixed_distance = Database.sqlite_version_info >= (3, 28, 0)
|
2019-10-16 02:55:49 +08:00
|
|
|
supports_aggregate_filter_clause = Database.sqlite_version_info >= (3, 30, 1)
|
2019-11-04 21:47:58 +08:00
|
|
|
supports_order_by_nulls_modifier = Database.sqlite_version_info >= (3, 30, 0)
|
2020-03-18 10:00:28 +08:00
|
|
|
order_by_nulls_first = True
|
2019-06-09 08:56:37 +08:00
|
|
|
|
2020-05-27 06:25:45 +08:00
|
|
|
@cached_property
|
|
|
|
def introspected_field_types(self):
|
|
|
|
return{
|
|
|
|
**super().introspected_field_types,
|
|
|
|
'BigAutoField': 'AutoField',
|
|
|
|
'DurationField': 'BigIntegerField',
|
|
|
|
'GenericIPAddressField': 'CharField',
|
|
|
|
'SmallAutoField': 'AutoField',
|
|
|
|
}
|
|
|
|
|
2019-06-09 08:56:37 +08:00
|
|
|
@cached_property
|
|
|
|
def supports_json_field(self):
|
|
|
|
try:
|
|
|
|
with self.connection.cursor() as cursor, transaction.atomic():
|
|
|
|
cursor.execute('SELECT JSON(\'{"a": "b"}\')')
|
|
|
|
except OperationalError:
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
|
|
can_introspect_json_field = property(operator.attrgetter('supports_json_field'))
|