1818
1919
2020class DatabaseWrapper (BaseDatabaseWrapper ):
21- vendor = ' spanner'
22- display_name = ' Cloud Spanner'
21+ vendor = " spanner"
22+ display_name = " Cloud Spanner"
2323
2424 # Mapping of Field objects to their column types.
2525 # https://cloud.google.com/spanner/docs/data-types#date-type
2626 data_types = {
27- ' AutoField' : ' INT64' ,
28- ' BigAutoField' : ' INT64' ,
29- ' BinaryField' : ' BYTES(MAX)' ,
30- ' BooleanField' : ' BOOL' ,
31- ' CharField' : ' STRING(%(max_length)s)' ,
32- ' DateField' : ' DATE' ,
33- ' DateTimeField' : ' TIMESTAMP' ,
34- ' DecimalField' : ' FLOAT64' ,
35- ' DurationField' : ' INT64' ,
36- ' EmailField' : ' STRING(%(max_length)s)' ,
37- ' FileField' : ' STRING(%(max_length)s)' ,
38- ' FilePathField' : ' STRING(%(max_length)s)' ,
39- ' FloatField' : ' FLOAT64' ,
40- ' IntegerField' : ' INT64' ,
41- ' BigIntegerField' : ' INT64' ,
42- ' IPAddressField' : ' STRING(15)' ,
43- ' GenericIPAddressField' : ' STRING(39)' ,
44- ' NullBooleanField' : ' BOOL' ,
45- ' OneToOneField' : ' INT64' ,
46- ' PositiveIntegerField' : ' INT64' ,
47- ' PositiveSmallIntegerField' : ' INT64' ,
48- ' SlugField' : ' STRING(%(max_length)s)' ,
49- ' SmallAutoField' : ' INT64' ,
50- ' SmallIntegerField' : ' INT64' ,
51- ' TextField' : ' STRING(MAX)' ,
52- ' TimeField' : ' TIMESTAMP' ,
53- ' UUIDField' : ' STRING(32)' ,
27+ " AutoField" : " INT64" ,
28+ " BigAutoField" : " INT64" ,
29+ " BinaryField" : " BYTES(MAX)" ,
30+ " BooleanField" : " BOOL" ,
31+ " CharField" : " STRING(%(max_length)s)" ,
32+ " DateField" : " DATE" ,
33+ " DateTimeField" : " TIMESTAMP" ,
34+ " DecimalField" : " FLOAT64" ,
35+ " DurationField" : " INT64" ,
36+ " EmailField" : " STRING(%(max_length)s)" ,
37+ " FileField" : " STRING(%(max_length)s)" ,
38+ " FilePathField" : " STRING(%(max_length)s)" ,
39+ " FloatField" : " FLOAT64" ,
40+ " IntegerField" : " INT64" ,
41+ " BigIntegerField" : " INT64" ,
42+ " IPAddressField" : " STRING(15)" ,
43+ " GenericIPAddressField" : " STRING(39)" ,
44+ " NullBooleanField" : " BOOL" ,
45+ " OneToOneField" : " INT64" ,
46+ " PositiveIntegerField" : " INT64" ,
47+ " PositiveSmallIntegerField" : " INT64" ,
48+ " SlugField" : " STRING(%(max_length)s)" ,
49+ " SmallAutoField" : " INT64" ,
50+ " SmallIntegerField" : " INT64" ,
51+ " TextField" : " STRING(MAX)" ,
52+ " TimeField" : " TIMESTAMP" ,
53+ " UUIDField" : " STRING(32)" ,
5454 }
5555 operators = {
56- ' exact' : ' = %s' ,
57- ' iexact' : ' REGEXP_CONTAINS(%s, %%%%s)' ,
56+ " exact" : " = %s" ,
57+ " iexact" : " REGEXP_CONTAINS(%s, %%%%s)" ,
5858 # contains uses REGEXP_CONTAINS instead of LIKE to allow
5959 # DatabaseOperations.prep_for_like_query() to do regular expression
6060 # escaping. prep_for_like_query() is called for all the lookups that
6161 # use REGEXP_CONTAINS except regex/iregex (see
6262 # django.db.models.lookups.PatternLookup).
63- ' contains' : ' REGEXP_CONTAINS(%s, %%%%s)' ,
64- ' icontains' : ' REGEXP_CONTAINS(%s, %%%%s)' ,
65- 'gt' : ' > %s' ,
66- ' gte' : ' >= %s' ,
67- 'lt' : ' < %s' ,
68- ' lte' : ' <= %s' ,
63+ " contains" : " REGEXP_CONTAINS(%s, %%%%s)" ,
64+ " icontains" : " REGEXP_CONTAINS(%s, %%%%s)" ,
65+ "gt" : " > %s" ,
66+ " gte" : " >= %s" ,
67+ "lt" : " < %s" ,
68+ " lte" : " <= %s" ,
6969 # Using REGEXP_CONTAINS instead of STARTS_WITH and ENDS_WITH for the
7070 # same reasoning as described above for 'contains'.
71- ' startswith' : ' REGEXP_CONTAINS(%s, %%%%s)' ,
72- ' endswith' : ' REGEXP_CONTAINS(%s, %%%%s)' ,
73- ' istartswith' : ' REGEXP_CONTAINS(%s, %%%%s)' ,
74- ' iendswith' : ' REGEXP_CONTAINS(%s, %%%%s)' ,
75- ' regex' : ' REGEXP_CONTAINS(%s, %%%%s)' ,
76- ' iregex' : ' REGEXP_CONTAINS(%s, %%%%s)' ,
71+ " startswith" : " REGEXP_CONTAINS(%s, %%%%s)" ,
72+ " endswith" : " REGEXP_CONTAINS(%s, %%%%s)" ,
73+ " istartswith" : " REGEXP_CONTAINS(%s, %%%%s)" ,
74+ " iendswith" : " REGEXP_CONTAINS(%s, %%%%s)" ,
75+ " regex" : " REGEXP_CONTAINS(%s, %%%%s)" ,
76+ " iregex" : " REGEXP_CONTAINS(%s, %%%%s)" ,
7777 }
7878
7979 # pattern_esc is used to generate SQL pattern lookup clauses when the
8080 # right-hand side of the lookup isn't a raw string (it might be an
8181 # expression or the result of a bilateral transformation). In those cases,
8282 # special characters for REGEXP_CONTAINS operators (e.g. \, *, _) must be
8383 # escaped on database side.
84- pattern_esc = r'REPLACE(REPLACE(REPLACE({}, "\\", "\\\\"), "%%", r"\%%"), "_", r"\_")'
84+ pattern_esc = (
85+ r'REPLACE(REPLACE(REPLACE({}, "\\", "\\\\"), "%%", r"\%%"), "_", r"\_")'
86+ )
8587 # These are all no-ops in favor of using REGEXP_CONTAINS in the customized
8688 # lookups.
8789 pattern_ops = {
88- ' contains' : '' ,
89- ' icontains' : '' ,
90- ' startswith' : '' ,
91- ' istartswith' : '' ,
92- ' endswith' : '' ,
93- ' iendswith' : '' ,
90+ " contains" : "" ,
91+ " icontains" : "" ,
92+ " startswith" : "" ,
93+ " istartswith" : "" ,
94+ " endswith" : "" ,
95+ " iendswith" : "" ,
9496 }
9597
9698 Database = Database
@@ -104,19 +106,19 @@ class DatabaseWrapper(BaseDatabaseWrapper):
104106
105107 @property
106108 def instance (self ):
107- return spanner .Client ().instance (self .settings_dict [' INSTANCE' ])
109+ return spanner .Client ().instance (self .settings_dict [" INSTANCE" ])
108110
109111 @property
110112 def _nodb_connection (self ):
111113 raise NotImplementedError ('Spanner does not have a "no db" connection.' )
112114
113115 def get_connection_params (self ):
114116 return {
115- ' project' : self .settings_dict [' PROJECT' ],
116- 'instance' : self .settings_dict [' INSTANCE' ],
117- 'database' : self .settings_dict [' NAME' ],
118- ' user_agent' : ' django_spanner/0.0.1' ,
119- ** self .settings_dict [' OPTIONS' ],
117+ " project" : self .settings_dict [" PROJECT" ],
118+ "instance_id" : self .settings_dict [" INSTANCE" ],
119+ "database_id" : self .settings_dict [" NAME" ],
120+ " user_agent" : " django_spanner/0.0.1" ,
121+ ** self .settings_dict [" OPTIONS" ],
120122 }
121123
122124 def get_new_connection (self , conn_params ):
@@ -137,7 +139,7 @@ def is_usable(self):
137139 return False
138140 try :
139141 # Use a cursor directly, bypassing Django's utilities.
140- self .connection .cursor ().execute (' SELECT 1' )
142+ self .connection .cursor ().execute (" SELECT 1" )
141143 except Database .Error :
142144 return False
143145 else :
0 commit comments