Fixed #31030 -- Registered SQLite functions as deterministic on Python 3.8+.
This commit is contained in:
parent
513948735b
commit
026719cf17
|
@ -24,6 +24,7 @@ from django.utils.asyncio import async_unsafe
|
|||
from django.utils.dateparse import parse_datetime, parse_time
|
||||
from django.utils.duration import duration_microseconds
|
||||
from django.utils.regex_helper import _lazy_re_compile
|
||||
from django.utils.version import PY38
|
||||
|
||||
from .client import DatabaseClient # isort:skip
|
||||
from .creation import DatabaseCreation # isort:skip
|
||||
|
@ -202,49 +203,56 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
|||
@async_unsafe
|
||||
def get_new_connection(self, conn_params):
|
||||
conn = Database.connect(**conn_params)
|
||||
conn.create_function("django_date_extract", 2, _sqlite_datetime_extract)
|
||||
conn.create_function("django_date_trunc", 2, _sqlite_date_trunc)
|
||||
conn.create_function('django_datetime_cast_date', 3, _sqlite_datetime_cast_date)
|
||||
conn.create_function('django_datetime_cast_time', 3, _sqlite_datetime_cast_time)
|
||||
conn.create_function('django_datetime_extract', 4, _sqlite_datetime_extract)
|
||||
conn.create_function('django_datetime_trunc', 4, _sqlite_datetime_trunc)
|
||||
conn.create_function("django_time_extract", 2, _sqlite_time_extract)
|
||||
conn.create_function("django_time_trunc", 2, _sqlite_time_trunc)
|
||||
conn.create_function("django_time_diff", 2, _sqlite_time_diff)
|
||||
conn.create_function("django_timestamp_diff", 2, _sqlite_timestamp_diff)
|
||||
conn.create_function("django_format_dtdelta", 3, _sqlite_format_dtdelta)
|
||||
conn.create_function('regexp', 2, _sqlite_regexp)
|
||||
conn.create_function('ACOS', 1, none_guard(math.acos))
|
||||
conn.create_function('ASIN', 1, none_guard(math.asin))
|
||||
conn.create_function('ATAN', 1, none_guard(math.atan))
|
||||
conn.create_function('ATAN2', 2, none_guard(math.atan2))
|
||||
conn.create_function('BITXOR', 2, none_guard(operator.xor))
|
||||
conn.create_function('CEILING', 1, none_guard(math.ceil))
|
||||
conn.create_function('COS', 1, none_guard(math.cos))
|
||||
conn.create_function('COT', 1, none_guard(lambda x: 1 / math.tan(x)))
|
||||
conn.create_function('DEGREES', 1, none_guard(math.degrees))
|
||||
conn.create_function('EXP', 1, none_guard(math.exp))
|
||||
conn.create_function('FLOOR', 1, none_guard(math.floor))
|
||||
conn.create_function('LN', 1, none_guard(math.log))
|
||||
conn.create_function('LOG', 2, none_guard(lambda x, y: math.log(y, x)))
|
||||
conn.create_function('LPAD', 3, _sqlite_lpad)
|
||||
conn.create_function('MD5', 1, none_guard(lambda x: hashlib.md5(x.encode()).hexdigest()))
|
||||
conn.create_function('MOD', 2, none_guard(math.fmod))
|
||||
conn.create_function('PI', 0, lambda: math.pi)
|
||||
conn.create_function('POWER', 2, none_guard(operator.pow))
|
||||
conn.create_function('RADIANS', 1, none_guard(math.radians))
|
||||
conn.create_function('REPEAT', 2, none_guard(operator.mul))
|
||||
conn.create_function('REVERSE', 1, none_guard(lambda x: x[::-1]))
|
||||
conn.create_function('RPAD', 3, _sqlite_rpad)
|
||||
conn.create_function('SHA1', 1, none_guard(lambda x: hashlib.sha1(x.encode()).hexdigest()))
|
||||
conn.create_function('SHA224', 1, none_guard(lambda x: hashlib.sha224(x.encode()).hexdigest()))
|
||||
conn.create_function('SHA256', 1, none_guard(lambda x: hashlib.sha256(x.encode()).hexdigest()))
|
||||
conn.create_function('SHA384', 1, none_guard(lambda x: hashlib.sha384(x.encode()).hexdigest()))
|
||||
conn.create_function('SHA512', 1, none_guard(lambda x: hashlib.sha512(x.encode()).hexdigest()))
|
||||
conn.create_function('SIGN', 1, none_guard(lambda x: (x > 0) - (x < 0)))
|
||||
conn.create_function('SIN', 1, none_guard(math.sin))
|
||||
conn.create_function('SQRT', 1, none_guard(math.sqrt))
|
||||
conn.create_function('TAN', 1, none_guard(math.tan))
|
||||
if PY38:
|
||||
create_deterministic_function = functools.partial(
|
||||
conn.create_function,
|
||||
deterministic=True,
|
||||
)
|
||||
else:
|
||||
create_deterministic_function = conn.create_function
|
||||
create_deterministic_function('django_date_extract', 2, _sqlite_datetime_extract)
|
||||
create_deterministic_function('django_date_trunc', 2, _sqlite_date_trunc)
|
||||
create_deterministic_function('django_datetime_cast_date', 3, _sqlite_datetime_cast_date)
|
||||
create_deterministic_function('django_datetime_cast_time', 3, _sqlite_datetime_cast_time)
|
||||
create_deterministic_function('django_datetime_extract', 4, _sqlite_datetime_extract)
|
||||
create_deterministic_function('django_datetime_trunc', 4, _sqlite_datetime_trunc)
|
||||
create_deterministic_function('django_time_extract', 2, _sqlite_time_extract)
|
||||
create_deterministic_function('django_time_trunc', 2, _sqlite_time_trunc)
|
||||
create_deterministic_function('django_time_diff', 2, _sqlite_time_diff)
|
||||
create_deterministic_function('django_timestamp_diff', 2, _sqlite_timestamp_diff)
|
||||
create_deterministic_function('django_format_dtdelta', 3, _sqlite_format_dtdelta)
|
||||
create_deterministic_function('regexp', 2, _sqlite_regexp)
|
||||
create_deterministic_function('ACOS', 1, none_guard(math.acos))
|
||||
create_deterministic_function('ASIN', 1, none_guard(math.asin))
|
||||
create_deterministic_function('ATAN', 1, none_guard(math.atan))
|
||||
create_deterministic_function('ATAN2', 2, none_guard(math.atan2))
|
||||
create_deterministic_function('BITXOR', 2, none_guard(operator.xor))
|
||||
create_deterministic_function('CEILING', 1, none_guard(math.ceil))
|
||||
create_deterministic_function('COS', 1, none_guard(math.cos))
|
||||
create_deterministic_function('COT', 1, none_guard(lambda x: 1 / math.tan(x)))
|
||||
create_deterministic_function('DEGREES', 1, none_guard(math.degrees))
|
||||
create_deterministic_function('EXP', 1, none_guard(math.exp))
|
||||
create_deterministic_function('FLOOR', 1, none_guard(math.floor))
|
||||
create_deterministic_function('LN', 1, none_guard(math.log))
|
||||
create_deterministic_function('LOG', 2, none_guard(lambda x, y: math.log(y, x)))
|
||||
create_deterministic_function('LPAD', 3, _sqlite_lpad)
|
||||
create_deterministic_function('MD5', 1, none_guard(lambda x: hashlib.md5(x.encode()).hexdigest()))
|
||||
create_deterministic_function('MOD', 2, none_guard(math.fmod))
|
||||
create_deterministic_function('PI', 0, lambda: math.pi)
|
||||
create_deterministic_function('POWER', 2, none_guard(operator.pow))
|
||||
create_deterministic_function('RADIANS', 1, none_guard(math.radians))
|
||||
create_deterministic_function('REPEAT', 2, none_guard(operator.mul))
|
||||
create_deterministic_function('REVERSE', 1, none_guard(lambda x: x[::-1]))
|
||||
create_deterministic_function('RPAD', 3, _sqlite_rpad)
|
||||
create_deterministic_function('SHA1', 1, none_guard(lambda x: hashlib.sha1(x.encode()).hexdigest()))
|
||||
create_deterministic_function('SHA224', 1, none_guard(lambda x: hashlib.sha224(x.encode()).hexdigest()))
|
||||
create_deterministic_function('SHA256', 1, none_guard(lambda x: hashlib.sha256(x.encode()).hexdigest()))
|
||||
create_deterministic_function('SHA384', 1, none_guard(lambda x: hashlib.sha384(x.encode()).hexdigest()))
|
||||
create_deterministic_function('SHA512', 1, none_guard(lambda x: hashlib.sha512(x.encode()).hexdigest()))
|
||||
create_deterministic_function('SIGN', 1, none_guard(lambda x: (x > 0) - (x < 0)))
|
||||
create_deterministic_function('SIN', 1, none_guard(math.sin))
|
||||
create_deterministic_function('SQRT', 1, none_guard(math.sqrt))
|
||||
create_deterministic_function('TAN', 1, none_guard(math.tan))
|
||||
conn.create_aggregate('STDDEV_POP', 1, list_aggregate(statistics.pstdev))
|
||||
conn.create_aggregate('STDDEV_SAMP', 1, list_aggregate(statistics.stdev))
|
||||
conn.create_aggregate('VAR_POP', 1, list_aggregate(statistics.pvariance))
|
||||
|
|
|
@ -351,6 +351,10 @@ Models
|
|||
SQL on MySQL by using ``DELETE`` instead of ``TRUNCATE`` statements for
|
||||
tables which don't require resetting sequences.
|
||||
|
||||
* SQLite functions are now marked as :py:meth:`deterministic
|
||||
<sqlite3.Connection.create_function>` on Python 3.8+. This allows using them
|
||||
in check constraints and partial indexes.
|
||||
|
||||
Pagination
|
||||
~~~~~~~~~~
|
||||
|
||||
|
|
Loading…
Reference in New Issue