3

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

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

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

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

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

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

('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 等,但无济于事。

任何,任何帮助将不胜感激。

谢谢。

更新:我将“never_cache”装饰器添加到大多数视图函数中,希望也许可以关闭 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)')
4

1 回答 1

2

我将尝试自己回答这个问题。我对这个答案不太满意,因为它没有详细解释问题,部分原因是我无法弄清楚问题发生的确切原因。

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

不过,有趣的是,在我的测试中,当并发INSERT SQL 调用进行时,我没有发现它有任何问题。就我的测试而言,所讨论的问题主要在SELECT调用上明显地表现出来。据我所知,这一发现可能只是冰山一角。但众所周知,FreeTDS 不是生产就绪驱动程序。

我一直在评估 Easysoft 的商业 MSSQL 驱动程序SQL Server ODBC 驱动程序。在通过了与 FreeTDS 相同的一组测试之后,我对这里所拥有的一切感到满意。它工作得非常好,当然,值得一提的是,它支持一系列功能,包括重要的正确 Unicode 支持,而 FreeTDS 不支持。

于 2010-11-06T13:22:56.647 回答