/
__init__.py
95 lines (71 loc) · 2.57 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# Copyright 2020 Google LLC
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
import datetime
import os
# Monkey-patch AutoField to generate a random value since Cloud Spanner can't
# do that.
from uuid import uuid4
import pkg_resources
from django.db.models.fields import (
AutoField,
SmallAutoField,
BigAutoField,
Field,
)
# Monkey-patch google.DatetimeWithNanoseconds's __eq__ compare against
# datetime.datetime.
from google.api_core.datetime_helpers import DatetimeWithNanoseconds
from .expressions import register_expressions
from .functions import register_functions
from .lookups import register_lookups
from .utils import check_django_compatability
__version__ = pkg_resources.get_distribution("django-google-spanner").version
USE_EMULATOR = os.getenv("SPANNER_EMULATOR_HOST") is not None
check_django_compatability()
register_expressions()
register_functions()
register_lookups()
def gen_rand_int64():
# Credit to https://stackoverflow.com/a/3530326.
return uuid4().int & 0x7FFFFFFFFFFFFFFF
def autofield_init(self, *args, **kwargs):
kwargs["blank"] = True
Field.__init__(self, *args, **kwargs)
self.default = gen_rand_int64
AutoField.__init__ = autofield_init
SmallAutoField.__init__ = autofield_init
BigAutoField.__init__ = autofield_init
AutoField.db_returning = False
SmallAutoField.db_returning = False
BigAutoField.db_returning = False
AutoField.validators = []
SmallAutoField.validators = []
BigAutoField.validators = []
old_datetimewithnanoseconds_eq = getattr(
DatetimeWithNanoseconds, "__eq__", None
)
def datetimewithnanoseconds_eq(self, other):
if old_datetimewithnanoseconds_eq:
equal = old_datetimewithnanoseconds_eq(self, other)
if equal:
return True
elif type(self) is type(other):
return False
# Otherwise try to convert them to an equvialent form.
# See https://github.com/googleapis/python-spanner-django/issues/272
if isinstance(other, datetime.datetime):
return self.ctime() == other.ctime()
return False
DatetimeWithNanoseconds.__eq__ = datetimewithnanoseconds_eq
# Sanity check here since tests can't easily be run for this file:
if __name__ == "__main__":
from django.utils import timezone
UTC = timezone.utc
dt = datetime.datetime(2020, 1, 10, 2, 44, 57, 999, UTC)
dtns = DatetimeWithNanoseconds(2020, 1, 10, 2, 44, 57, 999, UTC)
equal = dtns == dt
if not equal:
raise Exception("%s\n!=\n%s" % (dtns, dt))