summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRamiro Morales <cramm0@gmail.com>2012-02-11 20:05:50 +0000
committerRamiro Morales <cramm0@gmail.com>2012-02-11 20:05:50 +0000
commitccc0e122d42dad0f645407c469383d85bae92048 (patch)
treef8b426928c0b1de3b64aa8cf8340f0f886f2af39
parent4b81d790a83e8710032ea58a8edbc8b8dab8fbcf (diff)
Fixed #7783 -- Made introspection of nullable columns more robust with Postgres.
Thanks bthomas AT ncorcle DOT com for the report and initial patch, and Claude Paroz for the final, complete patch. git-svn-id: http://code.djangoproject.com/svn/django/trunk@17508 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/db/backends/postgresql_psycopg2/introspection.py10
-rw-r--r--tests/regressiontests/introspection/models.py2
-rw-r--r--tests/regressiontests/introspection/tests.py8
3 files changed, 18 insertions, 2 deletions
diff --git a/django/db/backends/postgresql_psycopg2/introspection.py b/django/db/backends/postgresql_psycopg2/introspection.py
index 2ce579a9cf..0027ec5eaf 100644
--- a/django/db/backends/postgresql_psycopg2/introspection.py
+++ b/django/db/backends/postgresql_psycopg2/introspection.py
@@ -34,8 +34,16 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
def get_table_description(self, cursor, table_name):
"Returns a description of the table, with the DB-API cursor.description interface."
+ # 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
+ FROM information_schema.columns
+ WHERE table_name = %s""", [table_name])
+ null_map = dict(cursor.fetchall())
cursor.execute("SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name))
- return cursor.description
+ return [tuple([item for item in line[:6]] + [null_map[line[0]]==u'YES'])
+ for line in cursor.description]
def get_relations(self, cursor, table_name):
"""
diff --git a/tests/regressiontests/introspection/models.py b/tests/regressiontests/introspection/models.py
index da12f6e5cb..3b8383e601 100644
--- a/tests/regressiontests/introspection/models.py
+++ b/tests/regressiontests/introspection/models.py
@@ -5,7 +5,7 @@ class Reporter(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField()
- facebook_user_id = models.BigIntegerField()
+ facebook_user_id = models.BigIntegerField(null=True)
def __unicode__(self):
return u"%s %s" % (self.first_name, self.last_name)
diff --git a/tests/regressiontests/introspection/tests.py b/tests/regressiontests/introspection/tests.py
index 1835064fcd..fa2b6c5d73 100644
--- a/tests/regressiontests/introspection/tests.py
+++ b/tests/regressiontests/introspection/tests.py
@@ -78,6 +78,14 @@ class IntrospectionTests(TestCase):
['IntegerField', 'CharField', 'CharField', 'CharField', 'BigIntegerField']
)
+ def test_get_table_description_nullable(self):
+ cursor = connection.cursor()
+ desc = connection.introspection.get_table_description(cursor, Reporter._meta.db_table)
+ self.assertEqual(
+ [r[6] for r in desc],
+ [False, False, False, False, True]
+ )
+
# Regression test for #9991 - 'real' types in postgres
@skipUnlessDBFeature('has_real_datatype')
def test_postgresql_real_type(self):