You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

261 lines
9.7 KiB

  1. from django.db.models.aggregates import StdDev
  2. from django.db.utils import ProgrammingError
  3. from django.utils.functional import cached_property
  4. class BaseDatabaseFeatures(object):
  5. gis_enabled = False
  6. allows_group_by_pk = False
  7. allows_group_by_selected_pks = False
  8. empty_fetchmany_value = []
  9. update_can_self_select = True
  10. # Does the backend distinguish between '' and None?
  11. interprets_empty_strings_as_nulls = False
  12. # Does the backend allow inserting duplicate NULL rows in a nullable
  13. # unique field? All core backends implement this correctly, but other
  14. # databases such as SQL Server do not.
  15. supports_nullable_unique_constraints = True
  16. # Does the backend allow inserting duplicate rows when a unique_together
  17. # constraint exists and some fields are nullable but not all of them?
  18. supports_partially_nullable_unique_constraints = True
  19. can_use_chunked_reads = True
  20. can_return_id_from_insert = False
  21. has_bulk_insert = False
  22. uses_savepoints = False
  23. can_release_savepoints = False
  24. can_combine_inserts_with_and_without_auto_increment_pk = False
  25. # If True, don't use integer foreign keys referring to, e.g., positive
  26. # integer primary keys.
  27. related_fields_match_type = False
  28. allow_sliced_subqueries = True
  29. has_select_for_update = False
  30. has_select_for_update_nowait = False
  31. supports_select_related = True
  32. # Does the default test database allow multiple connections?
  33. # Usually an indication that the test database is in-memory
  34. test_db_allows_multiple_connections = True
  35. # Can an object be saved without an explicit primary key?
  36. supports_unspecified_pk = False
  37. # Can a fixture contain forward references? i.e., are
  38. # FK constraints checked at the end of transaction, or
  39. # at the end of each save operation?
  40. supports_forward_references = True
  41. # Does the backend truncate names properly when they are too long?
  42. truncates_names = False
  43. # Is there a REAL datatype in addition to floats/doubles?
  44. has_real_datatype = False
  45. supports_subqueries_in_group_by = True
  46. supports_bitwise_or = True
  47. # Is there a true datatype for uuid?
  48. has_native_uuid_field = False
  49. # Is there a true datatype for timedeltas?
  50. has_native_duration_field = False
  51. # Does the database driver support timedeltas as arguments?
  52. # This is only relevant when there is a native duration field.
  53. # Specifically, there is a bug with cx_Oracle:
  54. # https://bitbucket.org/anthony_tuininga/cx_oracle/issue/7/
  55. driver_supports_timedelta_args = False
  56. # Do time/datetime fields have microsecond precision?
  57. supports_microsecond_precision = True
  58. # Does the __regex lookup support backreferencing and grouping?
  59. supports_regex_backreferencing = True
  60. # Can date/datetime lookups be performed using a string?
  61. supports_date_lookup_using_string = True
  62. # Can datetimes with timezones be used?
  63. supports_timezones = True
  64. # Does the database have a copy of the zoneinfo database?
  65. has_zoneinfo_database = True
  66. # When performing a GROUP BY, is an ORDER BY NULL required
  67. # to remove any ordering?
  68. requires_explicit_null_ordering_when_grouping = False
  69. # Does the backend order NULL values as largest or smallest?
  70. nulls_order_largest = False
  71. # Is there a 1000 item limit on query parameters?
  72. supports_1000_query_parameters = True
  73. # Can an object have an autoincrement primary key of 0? MySQL says No.
  74. allows_auto_pk_0 = True
  75. # Do we need to NULL a ForeignKey out, or can the constraint check be
  76. # deferred
  77. can_defer_constraint_checks = False
  78. # date_interval_sql can properly handle mixed Date/DateTime fields and timedeltas
  79. supports_mixed_date_datetime_comparisons = True
  80. # Does the backend support tablespaces? Default to False because it isn't
  81. # in the SQL standard.
  82. supports_tablespaces = False
  83. # Does the backend reset sequences between tests?
  84. supports_sequence_reset = True
  85. # Can the backend determine reliably the length of a CharField?
  86. can_introspect_max_length = True
  87. # Can the backend determine reliably if a field is nullable?
  88. # Note that this is separate from interprets_empty_strings_as_nulls,
  89. # although the latter feature, when true, interferes with correct
  90. # setting (and introspection) of CharFields' nullability.
  91. # This is True for all core backends.
  92. can_introspect_null = True
  93. # Can the backend introspect the default value of a column?
  94. can_introspect_default = True
  95. # Confirm support for introspected foreign keys
  96. # Every database can do this reliably, except MySQL,
  97. # which can't do it for MyISAM tables
  98. can_introspect_foreign_keys = True
  99. # Can the backend introspect an AutoField, instead of an IntegerField?
  100. can_introspect_autofield = False
  101. # Can the backend introspect a BigIntegerField, instead of an IntegerField?
  102. can_introspect_big_integer_field = True
  103. # Can the backend introspect an BinaryField, instead of an TextField?
  104. can_introspect_binary_field = True
  105. # Can the backend introspect an DecimalField, instead of an FloatField?
  106. can_introspect_decimal_field = True
  107. # Can the backend introspect an IPAddressField, instead of an CharField?
  108. can_introspect_ip_address_field = False
  109. # Can the backend introspect a PositiveIntegerField, instead of an IntegerField?
  110. can_introspect_positive_integer_field = False
  111. # Can the backend introspect a SmallIntegerField, instead of an IntegerField?
  112. can_introspect_small_integer_field = False
  113. # Can the backend introspect a TimeField, instead of a DateTimeField?
  114. can_introspect_time_field = True
  115. # Support for the DISTINCT ON clause
  116. can_distinct_on_fields = False
  117. # Does the backend decide to commit before SAVEPOINT statements
  118. # when autocommit is disabled? http://bugs.python.org/issue8145#msg109965
  119. autocommits_when_autocommit_is_off = False
  120. # Does the backend prevent running SQL queries in broken transactions?
  121. atomic_transactions = True
  122. # Can we roll back DDL in a transaction?
  123. can_rollback_ddl = False
  124. # Can we issue more than one ALTER COLUMN clause in an ALTER TABLE?
  125. supports_combined_alters = False
  126. # Does it support foreign keys?
  127. supports_foreign_keys = True
  128. # Does it support CHECK constraints?
  129. supports_column_check_constraints = True
  130. # Does the backend support 'pyformat' style ("... %(name)s ...", {'name': value})
  131. # parameter passing? Note this can be provided by the backend even if not
  132. # supported by the Python driver
  133. supports_paramstyle_pyformat = True
  134. # Does the backend require literal defaults, rather than parameterized ones?
  135. requires_literal_defaults = False
  136. # Does the backend require a connection reset after each material schema change?
  137. connection_persists_old_columns = False
  138. # What kind of error does the backend throw when accessing closed cursor?
  139. closed_cursor_error_class = ProgrammingError
  140. # Does 'a' LIKE 'A' match?
  141. has_case_insensitive_like = True
  142. # Does the backend require the sqlparse library for splitting multi-line
  143. # statements before executing them?
  144. requires_sqlparse_for_splitting = True
  145. # Suffix for backends that don't support "SELECT xxx;" queries.
  146. bare_select_suffix = ''
  147. # If NULL is implied on columns without needing to be explicitly specified
  148. implied_column_null = False
  149. uppercases_column_names = False
  150. # Does the backend support "select for update" queries with limit (and offset)?
  151. supports_select_for_update_with_limit = True
  152. # Does the backend ignore null expressions in GREATEST and LEAST queries unless
  153. # every expression is null?
  154. greatest_least_ignores_nulls = False
  155. # Can the backend clone databases for parallel test execution?
  156. # Defaults to False to allow third-party backends to opt-in.
  157. can_clone_databases = False
  158. def __init__(self, connection):
  159. self.connection = connection
  160. @cached_property
  161. def supports_transactions(self):
  162. """Confirm support for transactions."""
  163. with self.connection.cursor() as cursor:
  164. cursor.execute('CREATE TABLE ROLLBACK_TEST (X INT)')
  165. self.connection.set_autocommit(False)
  166. cursor.execute('INSERT INTO ROLLBACK_TEST (X) VALUES (8)')
  167. self.connection.rollback()
  168. self.connection.set_autocommit(True)
  169. cursor.execute('SELECT COUNT(X) FROM ROLLBACK_TEST')
  170. count, = cursor.fetchone()
  171. cursor.execute('DROP TABLE ROLLBACK_TEST')
  172. return count == 0
  173. @cached_property
  174. def supports_stddev(self):
  175. """Confirm support for STDDEV and related stats functions."""
  176. try:
  177. self.connection.ops.check_expression_support(StdDev(1))
  178. return True
  179. except NotImplementedError:
  180. return False
  181. def introspected_boolean_field_type(self, field=None, created_separately=False):
  182. """
  183. What is the type returned when the backend introspects a BooleanField?
  184. The optional arguments may be used to give further details of the field to be
  185. introspected; in particular, they are provided by Django's test suite:
  186. field -- the field definition
  187. created_separately -- True if the field was added via a SchemaEditor's AddField,
  188. False if the field was created with the model
  189. Note that return value from this function is compared by tests against actual
  190. introspection results; it should provide expectations, not run an introspection
  191. itself.
  192. """
  193. if self.can_introspect_null and field and field.null:
  194. return 'NullBooleanField'
  195. return 'BooleanField'