Python 在Oracle中Django的计数失败
我正在尝试使用以下模型对oracle数据库进行查询:Python 在Oracle中Django的计数失败,python,sql,django,oracle,Python,Sql,Django,Oracle,我正在尝试使用以下模型对oracle数据库进行查询: class FCSTrunkValidation(Validation): card_transaction = models.CharField(max_length=10, db_column='card_trnsctn_seq', primary_key=True) card_number = models.CharField(max_length=16, db_column='card_num') use_da
class FCSTrunkValidation(Validation):
card_transaction = models.CharField(max_length=10, db_column='card_trnsctn_seq', primary_key=True)
card_number = models.CharField(max_length=16, db_column='card_num')
use_date = models.CharField(max_length=14, db_column='use_date')
device = models.ForeignKey('TrunkDevice', db_column='device_id')
agency_id = models.CharField(max_length=3, db_column='agency_id')
此查询:
# day is a datetime object
qs = FCSTrunkValidation.oracle_objects.all()
qs = qs.filter(use_date__startswith=day.strftime('%Y%m%d'))
当我做qs.count时,我得到了这个:
...
File "/home/diegueus9/dev/odm/local/lib/python2.7/site-packages/django/db/models/query.py", line 93, in __repr__
data = list(self[:REPR_OUTPUT_SIZE + 1])
File "/home/diegueus9/dev/odm/local/lib/python2.7/site-packages/django/db/models/query.py", line 108, in __len__
self._result_cache.extend(self._iter)
File "/home/diegueus9/dev/odm/local/lib/python2.7/site-packages/django/db/models/query.py", line 317, in iterator
for row in compiler.results_iter():
File "/home/diegueus9/dev/odm/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 775, in results_iter
for rows in self.execute_sql(MULTI):
File "/home/diegueus9/dev/odm/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 840, in execute_sql
cursor.execute(sql, params)
File "/home/diegueus9/dev/odm/local/lib/python2.7/site-packages/django/db/backends/util.py", line 41, in execute
return self.cursor.execute(sql, params)
File "/home/diegueus9/dev/odm/local/lib/python2.7/site-packages/django/db/backends/oracle/base.py", line 717, in execute
six.reraise(utils.DatabaseError, utils.DatabaseError(*tuple(e.args)), sys.exc_info()[2])
File "/home/diegueus9/dev/odm/local/lib/python2.7/site-packages/django/db/backends/oracle/base.py", line 710, in execute
return self.cursor.execute(query, self._param_generator(params))
DatabaseError: ORA-02395: exceeded call limit on IO usage
但是,如果我使用squirrel客户端执行查询,我得到了号码,那么django可能会执行额外的查询来引发错误?我怎样才能让django的计数工作
我曾想过使用原始sql,但后来在类似的部分中遇到了一个转义%的问题
软件包版本
Python==2.7.4
Django==1.5.4
cx Oracle==5.1.2
六=1.4.1
更新20131023
根据@alko的建议,我在第709行的django.db.backends.oracle.base中添加了一个print语句,如下所示:
print query, self._param_generator(params)
然后,我使用Squirrel中的那些参数执行该查询,仍然得到了计数的数目
我的手动查询是:
select count(*) from TBAAD300 where AGENCY_ID=201 and USE_DATE LIKE '20130930%'
django使用的查询是:
SELECT COUNT(*) FROM "TBAAD300" WHERE ("TBAAD300"."AGENCY_ID" = :arg0 AND "TBAAD300"."USE_DATE" LIKE TRANSLATE(:arg1 USING NCHAR_CS) ESCAPE TRANSLATE('\' USING NCHAR_CS) )
以[u'201',u'20130930%']作为参数
然后我在Squirrel中执行了相同的查询,结果是130410,但当django执行时,会出现相同的错误,由print语句打印的完整查询是:
ALTER SESSION SET NLS_TERRITORY = 'AMERICA' []
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS' NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF' TIME_ZONE = 'UTC' []
SELECT 1 FROM DUAL WHERE DUMMY LIKE TRANSLATE(:arg0 USING NCHAR_CS) ESCAPE TRANSLATE('\' USING NCHAR_CS) [u'X']
SELECT COUNT(*) FROM "TBAAD300" WHERE ("TBAAD300"."AGENCY_ID" = :arg0 AND "TBAAD300"."USE_DATE" LIKE TRANSLATE(:arg1 USING NCHAR_CS) ESCAPE TRANSLATE('\' USING NCHAR_CS) ) [u'201', u'20130930%']
Oracle是您的prod db吗?ORA-02395表示IO限制,似乎您的计数查询会导致对数据库中的一个大表进行完全扫描,并限制每个查询的块读取 我建议重新考虑你的数据模型,你能用DateField代替use_date field,用filteruse_date_gte=…,use_date_lte=。。。?在这种情况下,您可以通过在use_date字段上添加索引来大幅提高性能和IO使用率,因为count和like查询可以在适当的情况下使用它 此处添加了更新以精细格式化SQL 您的Oracle DBMS版本是什么?您是否使用相同的用户凭据运行语句?什么是您的用户可以帮助的资源限制 要检查资源消耗指标是什么,还可以在sql client中运行以下命令:
exec runstats_pkg.rs_start;
<YOUR statement>
exec runstats_pkg.rs_stop;
select * from stats where name like '%session logical reads%';
select * from stats where name like '%consistent gets%';
此外,执行计划可能很方便
set autotrace on;
<YOUR STATEMENT>
set autotrace off;
正如我在问题中所说的那样,我可以用Squirrel客户端在数据库中完美地执行相同的查询,并且没有出现错误。这就是为什么我问django count是否有传统的疑问。此外,不幸的是,这个模型是由另一个团队设计的,我不能改变这个模型。我怀疑客户端的魔力会发生,所以我不相信sqls是平等的。您能从squirrel提供SQL,并由django执行SQL吗?对于后者,在调试级别使用日志集运行脚本;或者只是在/home/diegueus9/dev/odm/local/lib/python2.7/site-packages/django/db/backends/oracle/base.py中的710行之前临时添加打印查询。SQL计划对这两个方面都有帮助。你也用绑定变量在squirrel中执行了吗?用进一步的问题更新了我的答案:顺便问一下,你有dba可以帮忙吗?似乎这是他们的职责范围。@alko我使用盲变量执行完全相同的查询,dba在海外,因为他们为我公司的提供商工作,他们对我与django的问题不感兴趣。