PageRenderTime 48ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/django/db/backends/mysql/introspection.py

https://github.com/sesostris/django
Python | 105 lines | 84 code | 9 blank | 12 comment | 3 complexity | 5b378bcfde83e7388092686a3c8ff325 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. import re
  2. from .base import FIELD_TYPE
  3. from django.db.backends import BaseDatabaseIntrospection
  4. from django.utils import six
  5. foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)")
  6. class DatabaseIntrospection(BaseDatabaseIntrospection):
  7. data_types_reverse = {
  8. FIELD_TYPE.BLOB: 'TextField',
  9. FIELD_TYPE.CHAR: 'CharField',
  10. FIELD_TYPE.DECIMAL: 'DecimalField',
  11. FIELD_TYPE.NEWDECIMAL: 'DecimalField',
  12. FIELD_TYPE.DATE: 'DateField',
  13. FIELD_TYPE.DATETIME: 'DateTimeField',
  14. FIELD_TYPE.DOUBLE: 'FloatField',
  15. FIELD_TYPE.FLOAT: 'FloatField',
  16. FIELD_TYPE.INT24: 'IntegerField',
  17. FIELD_TYPE.LONG: 'IntegerField',
  18. FIELD_TYPE.LONGLONG: 'BigIntegerField',
  19. FIELD_TYPE.SHORT: 'IntegerField',
  20. FIELD_TYPE.STRING: 'CharField',
  21. FIELD_TYPE.TIMESTAMP: 'DateTimeField',
  22. FIELD_TYPE.TINY: 'IntegerField',
  23. FIELD_TYPE.TINY_BLOB: 'TextField',
  24. FIELD_TYPE.MEDIUM_BLOB: 'TextField',
  25. FIELD_TYPE.LONG_BLOB: 'TextField',
  26. FIELD_TYPE.VAR_STRING: 'CharField',
  27. }
  28. def get_table_list(self, cursor):
  29. "Returns a list of table names in the current database."
  30. cursor.execute("SHOW TABLES")
  31. return [row[0] for row in cursor.fetchall()]
  32. def get_table_description(self, cursor, table_name):
  33. "Returns a description of the table, with the DB-API cursor.description interface."
  34. cursor.execute("SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name))
  35. return cursor.description
  36. def _name_to_index(self, cursor, table_name):
  37. """
  38. Returns a dictionary of {field_name: field_index} for the given table.
  39. Indexes are 0-based.
  40. """
  41. return dict([(d[0], i) for i, d in enumerate(self.get_table_description(cursor, table_name))])
  42. def get_relations(self, cursor, table_name):
  43. """
  44. Returns a dictionary of {field_index: (field_index_other_table, other_table)}
  45. representing all relationships to the given table. Indexes are 0-based.
  46. """
  47. my_field_dict = self._name_to_index(cursor, table_name)
  48. constraints = self.get_key_columns(cursor, table_name)
  49. relations = {}
  50. for my_fieldname, other_table, other_field in constraints:
  51. other_field_index = self._name_to_index(cursor, other_table)[other_field]
  52. my_field_index = my_field_dict[my_fieldname]
  53. relations[my_field_index] = (other_field_index, other_table)
  54. return relations
  55. def get_key_columns(self, cursor, table_name):
  56. """
  57. Returns a list of (column_name, referenced_table_name, referenced_column_name) for all
  58. key columns in given table.
  59. """
  60. key_columns = []
  61. cursor.execute("""
  62. SELECT column_name, referenced_table_name, referenced_column_name
  63. FROM information_schema.key_column_usage
  64. WHERE table_name = %s
  65. AND table_schema = DATABASE()
  66. AND referenced_table_name IS NOT NULL
  67. AND referenced_column_name IS NOT NULL""", [table_name])
  68. key_columns.extend(cursor.fetchall())
  69. return key_columns
  70. def get_primary_key_column(self, cursor, table_name):
  71. """
  72. Returns the name of the primary key column for the given table
  73. """
  74. for column in six.iteritems(self.get_indexes(cursor, table_name)):
  75. if column[1]['primary_key']:
  76. return column[0]
  77. return None
  78. def get_indexes(self, cursor, table_name):
  79. cursor.execute("SHOW INDEX FROM %s" % self.connection.ops.quote_name(table_name))
  80. # Do a two-pass search for indexes: on first pass check which indexes
  81. # are multicolumn, on second pass check which single-column indexes
  82. # are present.
  83. rows = list(cursor.fetchall())
  84. multicol_indexes = set()
  85. for row in rows:
  86. if row[3] > 1:
  87. multicol_indexes.add(row[2])
  88. indexes = {}
  89. for row in rows:
  90. if row[2] in multicol_indexes:
  91. continue
  92. indexes[row[4]] = {'primary_key': (row[2] == 'PRIMARY'), 'unique': not bool(row[1])}
  93. return indexes