проблема unixODBC на сайте Django в Linux, которая исчезает при обновлении - PullRequest
3 голосов
/ 25 октября 2010

У меня есть вопрос о Django, unixODBC, FreeTDS, Apache2, mod_wsgi, который чем-то похож на этот вопрос , заданный ранее на SO.

У меня есть сайт Django, созданный для работы с последней версией Django, то есть 1.2.3. Он использует управляемые модели по большей части, в том смысле, что, за исключением информации о сеансе, Django ничего не записывает в БД, а только читает из нее.

БД, о которой идет речь, размещается на компьютере с Windows на MSSQL 2005.

Проект Django размещен на компьютере с Linux. Он обслуживается через mod_wsgi на Apache2. Соединение с БД осуществляется через печально известный FreeTDS и UnixODBC Duo. Последние версии как FreeTDS, так и unixODBC работают. На стороне Python для базы данных используются pyodbc и django-pyodbc.

Проект развернут на двух живых серверах Linux с одинаковыми настройками, которые находятся за балансировщиком нагрузки. Существует один сервер БД, к которому оба подключаются.

На действующих производственных серверах возникают некоторые проблемы. На страницах, которые запрашивают БД, чтобы получить записи для отображения, иногда, а я имею в виду, иногда выдается исключение с ошибкой:

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

Одна из странных особенностей этой загадки заключается в том, что всякий раз, когда вы получаете эту ошибку, простое нажатие кнопки «Обновить» в веб-браузере очищает ее и отображает страницу с записями, извлеченными из БД.

Сгенерированный 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)')

1 Ответ

2 голосов
/ 06 ноября 2010

Я собираюсь попытаться ответить на вопрос самостоятельно.Я не слишком доволен этим ответом, так как он не вдавается в подробности, объясняющие проблему, что частично объясняется тем, что мне не удалось выяснить точно , почему возникает проблема.

Проводя тестирование любыми возможными способами, я смог воспроизвести проблему в своей среде разработки и воспроизвести ее, когда захочу.По какой-то причине, которая может быть связана либо с ошибкой во FreeTDS, либо с каким-то ограничением, с которым я еще не сталкивался в документации, драйвер FreeTDS начинает выдавать ошибки, упомянутые в приведенном выше вопросе, когда параллельные запросысделано в приложение, которое, в свою очередь, попадает в базу данных через FreeTDS.Даже когда всего два пользователя одновременно просматривают приложение, драйвер FreeTDS начинает выбрасывать ошибки повсюду.

Что интересно, возможно, хотя и то, что при тестировании я не обнаружил никаких проблем при одновременных INSERT вызовах SQL.Проблема, о которой идет речь, громко проявляется в основном на SELECT вызовах, в той степени, в которой идет мое тестирование.Насколько мне известно, это открытие может быть только верхушкой айсберга.Но общеизвестно, что FreeTDS не является драйвером, готовым к работе.

Я оценивал коммерческий драйвер MSSQL от Easysoft, Драйвер ODBC для SQL Server .Пройдя через тот же набор тестов, что и FreeTDS, я доволен тем, что у меня есть.Он работает очень хорошо, и, конечно, здесь стоит упомянуть, что он поддерживает множество функций, в том числе важную правильную поддержку Unicode, чего нет у FreeTDS.

...