| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 92ad508 commit d09ad61
10 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,7 +17,6 @@ | |||
| 17 | 17 | from .introspection import DatabaseIntrospection | |
| 18 | 18 | from .operations import DatabaseOperations | |
| 19 | 19 | from .schema import DatabaseSchemaEditor | |
| 20 | - from .validation import DatabaseValidation | ||
| 21 | 20 | ||
| 22 | 21 | ||
| 23 | 22 | class DatabaseWrapper(BaseDatabaseWrapper): | |
@@ -34,7 +33,7 @@ class DatabaseWrapper(BaseDatabaseWrapper): | |||
| 34 | 33 | "CharField": "STRING(%(max_length)s)", | |
| 35 | 34 | "DateField": "DATE", | |
| 36 | 35 | "DateTimeField": "TIMESTAMP", | |
| 37 | - "DecimalField": "FLOAT64", | ||
| 36 | + "DecimalField": "NUMERIC", | ||
| 38 | 37 | "DurationField": "INT64", | |
| 39 | 38 | "EmailField": "STRING(%(max_length)s)", | |
| 40 | 39 | "FileField": "STRING(%(max_length)s)", | |
@@ -104,7 +103,6 @@ class DatabaseWrapper(BaseDatabaseWrapper): | |||
| 104 | 103 | introspection_class = DatabaseIntrospection | |
| 105 | 104 | ops_class = DatabaseOperations | |
| 106 | 105 | client_class = DatabaseClient | |
| 107 | - validation_class = DatabaseValidation | ||
| 108 | 106 | ||
| 109 | 107 | @property | |
| 110 | 108 | def instance(self): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -233,10 +233,6 @@ class DatabaseFeatures(BaseDatabaseFeatures): | |||
| 233 | 233 | "queries.test_bulk_update.BulkUpdateTests.test_large_batch", | |
| 234 | 234 | # Spanner doesn't support random ordering. | |
| 235 | 235 | "ordering.tests.OrderingTests.test_random_ordering", | |
| 236 | - # No matching signature for function MOD for argument types: FLOAT64, | ||
| 237 | - # FLOAT64. Supported signatures: MOD(INT64, INT64) | ||
| 238 | - "db_functions.math.test_mod.ModTests.test_decimal", | ||
| 239 | - "db_functions.math.test_mod.ModTests.test_float", | ||
| 240 | 236 | # casting DateField to DateTimeField adds an unexpected hour: | |
| 241 | 237 | # https://github.com/googleapis/python-spanner-django/issues/260 | |
| 242 | 238 | "db_functions.comparison.test_cast.CastTests.test_cast_from_db_date_to_datetime", | |
@@ -364,6 +360,11 @@ class DatabaseFeatures(BaseDatabaseFeatures): | |||
| 364 | 360 | "model_formsets.tests.ModelFormsetTest.test_prevent_change_outer_model_and_create_invalid_data", | |
| 365 | 361 | "model_formsets_regress.tests.FormfieldShouldDeleteFormTests.test_no_delete", | |
| 366 | 362 | "model_formsets_regress.tests.FormsetTests.test_extraneous_query_is_not_run", | |
| 363 | + # Numeric field is not supported in primary key/unique key. | ||
| 364 | + "model_formsets.tests.ModelFormsetTest.test_inline_formsets_with_custom_pk", | ||
| 365 | + "model_forms.tests.ModelFormBaseTest.test_exclude_and_validation", | ||
| 366 | + "model_forms.tests.UniqueTest.test_unique_together", | ||
| 367 | + "model_forms.tests.UniqueTest.test_override_unique_together_message", | ||
| 367 | 368 | # os.chmod() doesn't work on Kokoro? | |
| 368 | 369 | "file_uploads.tests.DirectoryCreationTests.test_readonly_root", | |
| 369 | 370 | # Tests that sometimes fail on Kokoro for unknown reasons. | |
@@ -1026,12 +1027,20 @@ class DatabaseFeatures(BaseDatabaseFeatures): | |||
| 1026 | 1027 | "db_functions.math.test_ceil.CeilTests.test_null", # noqa | |
| 1027 | 1028 | "db_functions.math.test_ceil.CeilTests.test_transform", # noqa | |
| 1028 | 1029 | "db_functions.math.test_cos.CosTests.test_null", # noqa | |
| 1030 | + "db_functions.math.test_cos.CosTests.test_transform", # noqa | ||
| 1029 | 1031 | "db_functions.math.test_cot.CotTests.test_null", # noqa | |
| 1032 | + "db_functions.math.test_degrees.DegreesTests.test_decimal", # noqa | ||
| 1030 | 1033 | "db_functions.math.test_degrees.DegreesTests.test_null", # noqa | |
| 1034 | + "db_functions.math.test_exp.ExpTests.test_decimal", # noqa | ||
| 1031 | 1035 | "db_functions.math.test_exp.ExpTests.test_null", # noqa | |
| 1036 | + "db_functions.math.test_exp.ExpTests.test_transform", # noqa | ||
| 1032 | 1037 | "db_functions.math.test_floor.FloorTests.test_null", # noqa | |
| 1038 | + "db_functions.math.test_ln.LnTests.test_decimal", # noqa | ||
| 1033 | 1039 | "db_functions.math.test_ln.LnTests.test_null", # noqa | |
| 1040 | + "db_functions.math.test_ln.LnTests.test_transform", # noqa | ||
| 1041 | + "db_functions.math.test_log.LogTests.test_decimal", # noqa | ||
| 1034 | 1042 | "db_functions.math.test_log.LogTests.test_null", # noqa | |
| 1043 | + "db_functions.math.test_mod.ModTests.test_float", # noqa | ||
| 1035 | 1044 | "db_functions.math.test_mod.ModTests.test_null", # noqa | |
| 1036 | 1045 | "db_functions.math.test_power.PowerTests.test_decimal", # noqa | |
| 1037 | 1046 | "db_functions.math.test_power.PowerTests.test_float", # noqa | |
@@ -1040,7 +1049,9 @@ class DatabaseFeatures(BaseDatabaseFeatures): | |||
| 1040 | 1049 | "db_functions.math.test_radians.RadiansTests.test_null", # noqa | |
| 1041 | 1050 | "db_functions.math.test_round.RoundTests.test_null", # noqa | |
| 1042 | 1051 | "db_functions.math.test_sin.SinTests.test_null", # noqa | |
| 1052 | + "db_functions.math.test_sqrt.SqrtTests.test_decimal", # noqa | ||
| 1043 | 1053 | "db_functions.math.test_sqrt.SqrtTests.test_null", # noqa | |
| 1054 | + "db_functions.math.test_sqrt.SqrtTests.test_transform", # noqa | ||
| 1044 | 1055 | "db_functions.math.test_tan.TanTests.test_null", # noqa | |
| 1045 | 1056 | "db_functions.tests.FunctionTests.test_func_transform_bilateral", # noqa | |
| 1046 | 1057 | "db_functions.tests.FunctionTests.test_func_transform_bilateral_multivalue", # noqa | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,6 +24,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection): | |||
| 24 | 24 | TypeCode.INT64: "IntegerField", | |
| 25 | 25 | TypeCode.STRING: "CharField", | |
| 26 | 26 | TypeCode.TIMESTAMP: "DateTimeField", | |
| 27 | + TypeCode.NUMERIC: "DecimalField", | ||
| 27 | 28 | } | |
| 28 | 29 | ||
| 29 | 30 | def get_field_type(self, data_type, description): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,7 +4,6 @@ | |||
| 4 | 4 | # license that can be found in the LICENSE file or at | |
| 5 | 5 | # https://developers.google.com/open-source/licenses/bsd | |
| 6 | 6 | ||
| 7 | - from django.db.models import DecimalField | ||
| 8 | 7 | from django.db.models.lookups import ( | |
| 9 | 8 | Contains, | |
| 10 | 9 | EndsWith, | |
@@ -233,13 +232,8 @@ def cast_param_to_float(self, compiler, connection): | |||
| 233 | 232 | """ | |
| 234 | 233 | sql, params = self.as_sql(compiler, connection) | |
| 235 | 234 | if params: | |
| 236 | - # Cast to DecimaField lookup values to float because | ||
| 237 | - # google.cloud.spanner_v1._helpers._make_value_pb() doesn't serialize | ||
| 238 | - # decimal.Decimal. | ||
| 239 | - if isinstance(self.lhs.output_field, DecimalField): | ||
| 240 | - params[0] = float(params[0]) | ||
| 241 | 235 | # Cast remote field lookups that must be integer but come in as string. | |
| 242 | - elif hasattr(self.lhs.output_field, "get_path_info"): | ||
| 236 | + if hasattr(self.lhs.output_field, "get_path_info"): | ||
| 243 | 237 | for i, field in enumerate( | |
| 244 | 238 | self.lhs.output_field.get_path_info()[-1].target_fields | |
| 245 | 239 | ): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -8,7 +8,6 @@ | |||
| 8 | 8 | import re | |
| 9 | 9 | from base64 import b64decode | |
| 10 | 10 | from datetime import datetime, time | |
| 11 | - from decimal import Decimal | ||
| 12 | 11 | from uuid import UUID | |
| 13 | 12 | ||
| 14 | 13 | from django.conf import settings | |
@@ -190,10 +189,11 @@ def adapt_decimalfield_value( | |||
| 190 | 189 | self, value, max_digits=None, decimal_places=None | |
| 191 | 190 | ): | |
| 192 | 191 | """ | |
| 193 | - Convert value from decimal.Decimal into float, for a direct mapping | ||
| 194 | - and correct serialization with RPCs to Cloud Spanner. | ||
| 192 | + Convert value from decimal.Decimal to spanner compatible value. | ||
| 193 | + Since spanner supports Numeric storage of decimal and python spanner | ||
| 194 | + takes care of the conversion so this is a no-op method call. | ||
| 195 | 195 | ||
| 196 | - :type value: :class:`~google.cloud.spanner_v1.types.Numeric` | ||
| 196 | + :type value: :class:`decimal.Decimal` | ||
| 197 | 197 | :param value: A decimal field value. | |
| 198 | 198 | ||
| 199 | 199 | :type max_digits: int | |
@@ -203,12 +203,10 @@ def adapt_decimalfield_value( | |||
| 203 | 203 | :param decimal_places: (Optional) The number of decimal places to store | |
| 204 | 204 | with the number. | |
| 205 | 205 | ||
| 206 | - :rtype: float | ||
| 207 | - :returns: Formatted value. | ||
| 206 | + :rtype: decimal.Decimal | ||
| 207 | + :returns: decimal value. | ||
| 208 | 208 | """ | |
| 209 | - if value is None: | ||
| 210 | - return None | ||
| 211 | - return float(value) | ||
| 209 | + return value | ||
| 212 | 210 | ||
| 213 | 211 | def adapt_timefield_value(self, value): | |
| 214 | 212 | """ | |
@@ -244,8 +242,6 @@ def get_db_converters(self, expression): | |||
| 244 | 242 | internal_type = expression.output_field.get_internal_type() | |
| 245 | 243 | if internal_type == "DateTimeField": | |
| 246 | 244 | converters.append(self.convert_datetimefield_value) | |
| 247 | - elif internal_type == "DecimalField": | ||
| 248 | - converters.append(self.convert_decimalfield_value) | ||
| 249 | 245 | elif internal_type == "TimeField": | |
| 250 | 246 | converters.append(self.convert_timefield_value) | |
| 251 | 247 | elif internal_type == "BinaryField": | |
@@ -311,26 +307,6 @@ def convert_datetimefield_value(self, value, expression, connection): | |||
| 311 | 307 | else dt | |
| 312 | 308 | ) | |
| 313 | 309 | ||
| 314 | - def convert_decimalfield_value(self, value, expression, connection): | ||
| 315 | - """Convert Spanner DecimalField value for Django. | ||
| 316 | - | ||
| 317 | - :type value: float | ||
| 318 | - :param value: A decimal field. | ||
| 319 | - | ||
| 320 | - :type expression: :class:`django.db.models.expressions.BaseExpression` | ||
| 321 | - :param expression: A query expression. | ||
| 322 | - | ||
| 323 | - :type connection: :class:`~google.cloud.cpanner_dbapi.connection.Connection` | ||
| 324 | - :param connection: Reference to a Spanner database connection. | ||
| 325 | - | ||
| 326 | - :rtype: :class:`Decimal` | ||
| 327 | - :returns: A converted decimal field. | ||
| 328 | - """ | ||
| 329 | - if value is None: | ||
| 330 | - return value | ||
| 331 | - # Cloud Spanner returns a float. | ||
| 332 | - return Decimal(str(value)) | ||
| 333 | - | ||
| 334 | 310 | def convert_timefield_value(self, value, expression, connection): | |
| 335 | 311 | """Convert Spanner TimeField value for Django. | |
| 336 | 312 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -84,7 +84,7 @@ def default(session): | |||
| 84 | 84 | "--cov-append", | |
| 85 | 85 | "--cov-config=.coveragerc", | |
| 86 | 86 | "--cov-report=", | |
| 87 | - "--cov-fail-under=68", | ||
| 87 | + "--cov-fail-under=65", | ||
| 88 | 88 | os.path.join("tests", "unit"), | |
| 89 | 89 | *session.posargs | |
| 90 | 90 | ) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,21 +7,24 @@ | |||
| 7 | 7 | from django_spanner.compiler import SQLCompiler | |
| 8 | 8 | from django.db.models import F | |
| 9 | 9 | from tests.unit.django_spanner.simple_test import SpannerSimpleTestClass | |
| 10 | + from decimal import Decimal | ||
| 10 | 11 | from .models import Number, Author | |
| 11 | 12 | ||
| 12 | 13 | ||
| 13 | 14 | class TestLookups(SpannerSimpleTestClass): | |
| 14 | 15 | def test_cast_param_to_float_lte_sql_query(self): | |
| 15 | 16 | ||
| 16 | - qs1 = Number.objects.filter(decimal_num__lte=1.1).values("decimal_num") | ||
| 17 | + qs1 = Number.objects.filter(decimal_num__lte=Decimal("1.1")).values( | ||
| 18 | + "decimal_num" | ||
| 19 | + ) | ||
| 17 | 20 | compiler = SQLCompiler(qs1.query, self.connection, "default") | |
| 18 | 21 | sql_compiled, params = compiler.as_sql() | |
| 19 | 22 | self.assertEqual( | |
| 20 | 23 | sql_compiled, | |
| 21 | 24 | "SELECT tests_number.decimal_num FROM tests_number WHERE " | |
| 22 | 25 | + "tests_number.decimal_num <= %s", | |
| 23 | 26 | ) | |
| 24 | - self.assertEqual(params, (1.1,)) | ||
| 27 | + self.assertEqual(params, (Decimal("1.1"),)) | ||
| 25 | 28 | ||
| 26 | 29 | def test_cast_param_to_float_for_int_field_query(self): | |
| 27 | 30 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,6 +7,7 @@ | |||
| 7 | 7 | from django.db.utils import DatabaseError | |
| 8 | 8 | from datetime import timedelta | |
| 9 | 9 | from tests.unit.django_spanner.simple_test import SpannerSimpleTestClass | |
| 10 | + from decimal import Decimal | ||
| 10 | 11 | ||
| 11 | 12 | ||
| 12 | 13 | class TestOperations(SpannerSimpleTestClass): | |
@@ -58,7 +59,8 @@ def test_adapt_datefield_value_none(self): | |||
| 58 | 59 | ||
| 59 | 60 | def test_adapt_decimalfield_value(self): | |
| 60 | 61 | self.assertIsInstance( | |
| 61 | - self.db_operations.adapt_decimalfield_value(value=1), float, | ||
| 62 | + self.db_operations.adapt_decimalfield_value(value=Decimal("1")), | ||
| 63 | + Decimal, | ||
| 62 | 64 | ) | |
| 63 | 65 | ||
| 64 | 66 | def test_adapt_decimalfield_value_none(self): | |
@@ -93,23 +95,6 @@ def test_adapt_timefield_value_none(self): | |||
| 93 | 95 | self.db_operations.adapt_timefield_value(value=None), | |
| 94 | 96 | ) | |
| 95 | 97 | ||
| 96 | - def test_convert_decimalfield_value(self): | ||
| 97 | - from decimal import Decimal | ||
| 98 | - | ||
| 99 | - self.assertIsInstance( | ||
| 100 | - self.db_operations.convert_decimalfield_value( | ||
| 101 | - value=1.0, expression=None, connection=None | ||
| 102 | - ), | ||
| 103 | - Decimal, | ||
| 104 | - ) | ||
| 105 | - | ||
| 106 | - def test_convert_decimalfield_value_none(self): | ||
| 107 | - self.assertIsNone( | ||
| 108 | - self.db_operations.convert_decimalfield_value( | ||
| 109 | - value=None, expression=None, connection=None | ||
| 110 | - ), | ||
| 111 | - ) | ||
| 112 | - | ||
| 113 | 98 | def test_convert_uuidfield_value(self): | |
| 114 | 99 | import uuid | |
| 115 | 100 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments