summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Kelly <ian.g.kelly@gmail.com>2007-12-11 02:22:40 +0000
committerIan Kelly <ian.g.kelly@gmail.com>2007-12-11 02:22:40 +0000
commited5eca598e6e0fced2262dafa052d5db1661d83a (patch)
tree6f3d68801351664edb267cd3fe85c7f8d3354a8f
parentf425cb8caabdd6af6d787c9f7e3f87f0856287ad (diff)
Fixed ORA-01461 error when trying to store more than 4000 bytes in a TextField under Oracle
git-svn-id: http://code.djangoproject.com/svn/django/trunk@6905 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/db/backends/oracle/base.py19
-rw-r--r--tests/regressiontests/model_regress/models.py10
2 files changed, 29 insertions, 0 deletions
diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py
index 24fda78427..cd830413fc 100644
--- a/django/db/backends/oracle/base.py
+++ b/django/db/backends/oracle/base.py
@@ -455,6 +455,23 @@ class FormatStylePlaceholderCursor(Database.Cursor):
else:
return tuple([smart_str(p, self.charset, True) for p in params])
+ def _guess_input_sizes(self, params_list):
+ # Mark any string parameter greater than 4000 characters as an NCLOB.
+ if isinstance(params_list[0], dict):
+ sizes = {}
+ iterators = [params.iteritems() for params in params_list]
+ else:
+ sizes = [None] * len(params_list[0])
+ iterators = [enumerate(params) for params in params_list]
+ for iterator in iterators:
+ for key, value in iterator:
+ if isinstance(value, basestring) and len(value) > 4000:
+ sizes[key] = Database.NCLOB
+ if isinstance(sizes, dict):
+ self.setinputsizes(**sizes)
+ else:
+ self.setinputsizes(*sizes)
+
def execute(self, query, params=None):
if params is None:
params = []
@@ -468,6 +485,7 @@ class FormatStylePlaceholderCursor(Database.Cursor):
if query.endswith(';') or query.endswith('/'):
query = query[:-1]
query = smart_str(query, self.charset) % tuple(args)
+ self._guess_input_sizes([params])
return Database.Cursor.execute(self, query, params)
def executemany(self, query, params=None):
@@ -484,6 +502,7 @@ class FormatStylePlaceholderCursor(Database.Cursor):
query = query[:-1]
query = smart_str(query, self.charset) % tuple(args)
new_param_list = [self._format_params(i) for i in params]
+ self._guess_input_sizes(new_param_list)
return Database.Cursor.executemany(self, query, new_param_list)
def fetchone(self):
diff --git a/tests/regressiontests/model_regress/models.py b/tests/regressiontests/model_regress/models.py
index 00c3bc96f0..02e73a5aa9 100644
--- a/tests/regressiontests/model_regress/models.py
+++ b/tests/regressiontests/model_regress/models.py
@@ -11,6 +11,7 @@ class Article(models.Model):
pub_date = models.DateTimeField()
status = models.IntegerField(blank=True, null=True, choices=CHOICES)
misc_data = models.CharField(max_length=100, blank=True)
+ article_text = models.TextField()
class Meta:
ordering = ('pub_date','headline')
@@ -41,5 +42,14 @@ Empty strings should be returned as Unicode
>>> a2 = Article.objects.get(pk=a.id)
>>> a2.misc_data
u''
+
+# TextFields can hold more than 4000 characters (this was broken in Oracle).
+>>> a3 = Article(headline="Really, really big", pub_date=datetime.now())
+>>> a3.article_text = "ABCDE" * 1000
+>>> a3.save()
+>>> a4 = Article.objects.get(pk=a3.id)
+>>> len(a4.article_text)
+5000
+
"""
}