代码之家  ›  专栏  ›  技术社区  ›  ayaz

Linux上的django站点上的unixodc问题在刷新时消失

  •  3
  • ayaz  · 技术社区  · 14 年前

    我有一个关于django、unixodc、freetds、apache2、mod_wsgi的问题,这与 this question 以前问过。

    我有一个django网站,建立在最新的django上,也就是1.2.3。它在很大程度上使用托管模型,因为除了会话信息之外,Django不会向数据库写入任何内容,只从中读取内容。

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

    Django项目托管在Linux机器上。它在阿帕奇2号公路上的摩德沃斯基公路上提供。数据库连接是通过臭名昭著的freetds和unixodc-duo。最新版本的freetds和unixodc都在运行。在python端,pyodbc和django-pyodbc用于数据库。

    该项目部署在两个Linux Live服务器上,其设置相同,位于负载均衡器后面。有一个数据库服务器同时连接到。

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

    ('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进行了测试,在那里,我也没有看到任何错误。我想在嵌入式模式下更改了Live服务器上的设置以使用mod wsgi,但有时仍然会出现错误。

    我真的被这件事缠住了。我不知道怎样才能更接近地弄清楚到底是什么导致了这个问题。我不确定我是否提供了所有有用的信息。如果我没有,请指出,我会更新问题。

    我不相信代码中有任何错误导致了这种情况。如果是这样的话,它在大多数或所有时间都不会起作用。我试过清除.pyc文件,重新启动apache等,但是没有用。

    任何帮助都将不胜感激。

    谢谢。

    更新 :我将“从不缓存”装饰附加到大多数视图函数,希望Django所做的任何小模型级缓存都可以关闭。但在直播服务器上这并没有起到任何作用。我现在真的疯了。

    更新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 回复  |  直到 14 年前
        1
  •  2
  •   ayaz    14 年前

    我打算亲自回答这个问题。我对这个答案不太满意,因为它没有详细解释这个问题,部分原因是我还没有弄清楚 确切地 问题发生的原因。

    通过任何我能想到的方法进行测试,我能够在我的开发环境中重现这个问题,并在我想要的任何时候重现它。出于某种原因,这可能是由于freetds中的一个bug或某种我在任何地方的文档中都没有遇到的限制,freetds驱动程序在向应用程序(在tur中)发出并发请求时开始抛出上述问题中提到的错误。n通过freetds访问数据库。即使只有两个用户同时浏览应用程序,Freetds驱动程序也会在任何地方抛出错误。

    不过,有趣的是,在我的测试中,我发现它在并发时没有任何问题。 插入 正在进行SQL调用。问题主要表现在 选择 调用,直到我的测试结束。据我所知,这一发现可能只是冰山一角。但大家都知道,Freetds并不是生产就绪的驱动程序。

    我一直在评估Easysoft的商业MSSQL驱动程序, SQL Server ODBC driver . 通过了我做的一组免费测试后,我对这里的测试感到满意。它工作得很好,当然,这里值得一提的是,它支持一系列功能,包括重要的适当的Unicode支持,而Freetds不支持。