Linux上的Django站点上的unixODBC问题在刷新时就消失了

时间:2010-10-25 17:38:41

标签: django apache2 mod-wsgi freetds unixodbc

我有一个关于Django,unixODBC,FreeTDS,Apache2,mod_wsgi的问题,这有点类似于之前在SO上提出的this question

我有一个Django网站,可以在最新的Django上运行,即1.2.3。它在大多数情况下使用托管模型,因为除了会话信息之外,Django没有任何内容写入数据库,只能从中读取。

有问题的数据库托管在MSSQL 2005上的Windows计算机上。

Django项目托管在Linux机器上。它在Apache2上的mod_wsgi上提供。数据库连接是通过臭名昭着的FreeTDS和unixODBC二人组。 FreeTDS和unixODBC的最新版本正在运行。在Python端,pyodbc和django-pyodbc用于DB的东西。

该项目部署在两个Linux实时服务器上,具有相同的设置,位于负载均衡器之后。有一个DB服务器都连接到。

在实时生产服务器上,存在一些间歇性问题。在查询数据库以获取要显示的记录的页面上,有时候,我的意思是,有时会抛出异常,并出现错误:

('IM001', '[IM001] [unixODBC][Driver Manager]Driver does not support this function (0) (SQLColAttribute)')

关于这个难题的一个奇怪的地方是,每当你收到这个错误时,只需在Web浏览器上点击刷新就会清除它并使用从数据库中提取的记录呈现页面。

发生错误时从调试输出生成的SQL非常简单:

SELECT COUNT(*) FROM [TABLE] WHERE ([TABLE].[category] = 5 AND [TABLE].[newRelease] = 1 )

在Django开发服务器上,当然不会出现这种情况。在开发机器上,mod_wsgi以守护进程模式运行,我多次遇到此错误。我通过在mod_python上部署测试,在那里我没有看到任何错误。然后我在嵌入模式下使用mod_wsgi进行测试,同时我没有看到任何错误。我认为更改了实时服务器上的设置以在嵌入模式下使用mod_wsgi,但错误有时仍会出现。

我真的很困惑。我不知道该怎样试着弄清楚究竟是什么导致了这个问题。我不确定我是否提供了所有有用的信息。如果我没有,请指出,我会更新问题。

我不相信代码中有任何错误并导致此问题。如果是这样的话,大多数或所有时间都不会起作用。我已经尝试在实时服务器上清除.pyc文件,重启Apache等,但无济于事。

任何,任何帮助将非常感谢。

感谢。

UPDATE :我为大多数视图函数添加了“never_cache”装饰器,希望可能关闭Django所做的任何小模型级缓存。但是在实时服务器上并没有真正做任何事情。我现在真的没有想法了。

UPDATE#2 :我在生成异常的代码周围的sql_sever/pyodbc/base.py(django-pyodbc)内部进行了一些日志记录。而且我有更多的SQL查询,显然,这些查询产生了难以捉摸的错误:

sql = SELECT * FROM (SELECT [TABLE].[id], [TABLE].[productID], [TABLE].[title], [TABLE].[price], [TABLE].[rrp], [TABLE].[saving], [TABLE].[hmvPoints], [TABLE].[availability], [TABLE].[shipping], [TABLE].[rating], [TABLE].[thumbnail], [TABLE].[details], [TABLE].[images], [TABLE].[certImage], [TABLE].[trackListing], [TABLE].[category], [TABLE].[subCategory], [TABLE].[genreId], [TABLE].[bestSeller], [TABLE].[preOrder], [TABLE].[newRelease], (ROW_NUMBER() OVER (ORDER BY [TABLE].[id] ASC)) AS [rn] FROM [TABLE] WHERE [TABLE].[productID] = ? ) AS X WHERE X.rn BETWEEN 1 AND 21

params = (799742,) 

exception = ('IM001', '[IM001] [unixODBC][Driver Manager]Driver does not support this function (0) (SQLColAttribute)')

sql = SELECT * FROM (SELECT (1) AS [a], (ROW_NUMBER() OVER (ORDER BY RAND() )) AS [rn] FROM [django_session] WHERE [django_session].[session_key] = ? ) AS X WHERE X.rn BETWEEN 1 AND 1

params = ('e4b669b40d10c336d62c8435198bf1db',)

exception = ('IM001', '[IM001] [unixODBC][Driver Manager]Driver does not support this function (0) (SQLColAttribute)')

1 个答案:

答案 0 :(得分:2)

我打算尝试自己回答这个问题。我对这个答案不太满意,因为它没有详细解释问题,这部分是由于我无法找出完全问题发生的原因。

通过我能想到的任何方式进行测试,我能够在我的开发环境中重现问题,并在我想要的时候重现它。出于某种原因,可能是由于FreeTDS中的错误或者我在任何地方的文档中都没有遇到的某种限制,FreeTDS驱动程序开始抛出上述问题中提到的错误,当并发请求是对应用程序进行了操作,而应用程序又通过FreeTDS访问数据库。即使只有两个用户同时浏览应用程序,FreeTDS驱动程序也开始在各处抛出错误。

有趣的是,或许,在我的测试中,我发现在进行并发 INSERT SQL调用时没有任何问题。有问题的问题主要在于 SELECT 调用,就我的测试而言。据我所知,这一发现可能只是冰山一角。但众所周知,FreeTDS不是生产就绪的驱动程序。

我一直在评估Easysoft的商业MSSQL驱动程序,SQL Server ODBC driver。通过我做FreeTDS的同一组测试后,我对这里的内容感到满意。它运行得非常好,当然,值得一提的是它支持一系列功能,包括重要的正确Unicode支持,FreeTDS没有。