浏览代码

Added AutoField introspection for PostgreSQL

Refs #23748.
Claude Paroz 10 年之前
父节点
当前提交
1a63093e22

+ 1 - 0
django/db/backends/postgresql_psycopg2/base.py

@@ -55,6 +55,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
     can_release_savepoints = True
     supports_tablespaces = True
     supports_transactions = True
+    can_introspect_autofield = True
     can_introspect_ip_address_field = True
     can_introspect_small_integer_field = True
     can_distinct_on_fields = True

+ 14 - 3
django/db/backends/postgresql_psycopg2/introspection.py

@@ -1,9 +1,13 @@
 from __future__ import unicode_literals
+from collections import namedtuple
 
 from django.db.backends import BaseDatabaseIntrospection, FieldInfo, TableInfo
 from django.utils.encoding import force_text
 
 
+FieldInfo = namedtuple('FieldInfo', FieldInfo._fields + ('default',))
+
+
 class DatabaseIntrospection(BaseDatabaseIntrospection):
     # Maps type codes to Django Field types.
     data_types_reverse = {
@@ -28,6 +32,12 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
 
     ignored_tables = []
 
+    def get_field_type(self, data_type, description):
+        field_type = super(DatabaseIntrospection, self).get_field_type(data_type, description)
+        if field_type == 'IntegerField' and description.default and 'nextval' in description.default:
+            return 'AutoField'
+        return field_type
+
     def get_table_list(self, cursor):
         """
         Returns a list of table and view names in the current database.
@@ -48,12 +58,13 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
         # As cursor.description does not return reliably the nullable property,
         # we have to query the information_schema (#7783)
         cursor.execute("""
-            SELECT column_name, is_nullable
+            SELECT column_name, is_nullable, column_default
             FROM information_schema.columns
             WHERE table_name = %s""", [table_name])
-        null_map = dict(cursor.fetchall())
+        field_map = dict((line[0], line[1:]) for line in cursor.fetchall())
         cursor.execute("SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name))
-        return [FieldInfo(*((force_text(line[0]),) + line[1:6] + (null_map[force_text(line[0])] == 'YES',)))
+        return [FieldInfo(*((force_text(line[0]),) + line[1:6]
+                            + (field_map[force_text(line[0])][0] == 'YES', field_map[force_text(line[0])][1])))
                 for line in cursor.description]
 
     def get_relations(self, cursor, table_name):

+ 3 - 1
docs/releases/1.8.txt

@@ -320,7 +320,9 @@ Management Commands
 
 * :djadmin:`runserver` now uses daemon threads for faster reloading.
 
-* :djadmin:`inspectdb` now outputs ``Meta.unique_together``.
+* :djadmin:`inspectdb` now outputs ``Meta.unique_together``. It is also able to
+  introspect :class:`~django.db.models.AutoField` for MySQL and PostgreSQL
+  databases.
 
 * When calling management commands from code through :ref:`call_command
   <call-command>` and passing options, the option name can match the command