Подключите MySQL 3.23 с pyodbc 3.07
Я пытаюсь подключиться к старому серверу MySQL 3.23 от клиента Ubuntu 16 с UnixODBC и pyodbc 3.07. Я пробовал три (3) версии MySQL Connector/ODBC и два (2) из MariaDB:
MySQL-ODBC 5.3.9 поддерживает только новый метод аутентификации mysql. Поэтому он не может подключиться.
MySQL-ODBC 5.1.13 имеет переключатель для метода аутентификации, но говорит мне о pyodbc.connect(dsn)
: [MySQL][ODBC 5.1 Driver]Driver does not support server versions under 4.1.1
MySQL-ODBC 3.51 есть два вопроса:
- выдает
[MySQL][ODBC 3.51 Driver]Transactions are not enabled (4000) (SQLSetConnnectAttr(SQL_ATTR_AUTOCOMMIT))
поскольку pyodbc устанавливает autocommit в false по умолчанию. - дает мне соединение, когда я соединяюсь с
pyodbc.connect(dsn, autocommit=True)
. Соединение дает мне курсор но курсора.execute (sql) выбрасывает исключение('HY000', 'The driver did not supply an error!')
.
проверка соединения с isql из оболочки через isql -v [dsn]
дает мне сеанс, но терпит неудачу во всех заявлениях с [ISQL]ERROR: Could not SQLExecute
. Так это кажется, это проблема unixodbc.
Я установил mysql-client. Но программа mysql не может подключить сервер.
версию MariaDB-клиент подключиться к базе данных и даже выполнять инструкции. Это выглядит более многообещающе.
Я скачал MariaDB ODBC-драйвер 3.0.2. Использование этого драйвера с isql возвращает ошибку:[S1000][unixODBC][ma-3.0.2]Plugin old_password could not be loaded: lib/mariadb/plugin/old_password.so: cannot open shared object file: No such file or directory
. С таким ответом можно работать. Существует ODBC-опция PLUGIN_DIR, но я не знаю, где взять плагин.
MariaDB ODBC-драйвер 2.0.13 дает мне ('HY000', "[HY000] [unixODBC][ma-2.0.13]You have an error in your SQL syntax near 'SQL_AUTO_IS_NULL=0' at line 1 (1064) (SQLDriverConnect)")
on connect. Поскольку, похоже, нет возможности изменить это. Здесь тупик.
Я хотел бы знать, есть ли способ получить доступ к этому старому MySql через unixodbc/pyodbc?
или кто-нибудь знает где взять старый_пароль плагин.поэтому для версию MariaDB?
mariadb-клиент, установленный через apt-get, может подключиться, поэтому должен быть способ.
2 ответов
я провел день или около того, ковыряясь в этом, и не думаю, что это возможно без значительных изменений в коде драйвера или чрезвычайно сложной для создания среды сборки для старых версий.
я помещаю это в ответ, чтобы другие люди не падали в ту же кроличью нору, что и я (или, еще лучше, чтобы другие люди могли продолжить, где я остановился, и фактически решить проблему!) ...и это не вписывалось в комментарий.
это будет немного том, извиняюсь.
обзор
я смог воспроизвести каждое из условий ошибки, которые вы упомянули в своем посте (спасибо за тщательный и отличный вопрос!) используя пару контейнеров Ubuntu 16.04,в MySQL 3.23 скачать доступно из Oracle, и все клиентские библиотеки, которые вы упомянули, и несколько других.
ниже то, что я нашел, пытаясь найти дополнительные решения в каждом месте вы отметили, а затем "далее шаги " - введите информацию и некоторые прозелитические о морали истории.
все эти тесты были проведены с последними версиями Python 2, UnixODBC и pyodbc
(via pip
) доступен на складе в Ubuntu 16.04 контейнер докер в 26/11/2017.
все используемые url связаны, но, если история есть какие-либо указания, они могут умереть со временем, учитывая, что многие из этого программного обеспечения находится на грани двух десятилетий. Я также рад опубликовать любой / все мои shellscripts/Dockerfiles / измененные источники драйверов, Если хотите; просто ping меня в комментариях.
old_password.так и MariaDB разъем / ODBC 3.0.2
Вы были правы, что это был вариант устранения неполадок с наибольшим потенциалом. Вот что я сделал:--107-->
во-первых, я установил разъем / ODBC 3.0.2 binary и попытался подключиться к нему через Python. Я попал в ту же ошибку, что и вы после настройки моего ODBC .ini
файлы данных источник по имени "Мария", а именно:
> pyodbc.connect('DRIVER={maria};Server=mysql;Database=mysql;User=admin;Password=admin')
pyodbc.Error: ('HY000', u'[HY000] [unixODBC][ma-3.0.2]Plugin old_password could not be loaded: lib/mariadb/plugin/old_password.so: cannot open shared object file: No such file or directory (2059) (SQLDriverConnect)')
код ODBC пытается, когда представлен сервер MySQL, объявляющий достаточно старый протокол аутентификации, загрузить скомпилированные Плагины, построенные для разъем / c драйвер MariaDB. strace
ing выход попыток подключения ODBC определил это.
old_password.so
оказывается компонентом драйвера Connector / C MariaDB, но не является библиотекой, включенной в двоичные версии этого драйвера. Интересный.
оказывается, что есть куча модулей плагинов, похожих на old_password
в комплекте с источником драйвера Connector / C. Я загрузил разъем / c 3.0.2 источники и открыл документацию, источники и систему сборки для тех плагинов типа"auth", которые были распространены как .so
файлы, чтобы посмотреть, что я мог найти.
я обнаружил, что различные компоненты Connector / C могут быть скомпилированы либо как плагины "статически" связан с основной библиотекой драйверов или как сами динамические библиотеки. Я говорю "статически" в кавычках, потому что процесс сборки для драйвера C создает как статический (.a
) и динамические (.so
) версии mariadbclient
, но если конкретный плагин объявлен как статический в системе сборки, код этого плагина статически включен в оба mariadbclient
артефакты.
источники old_password.so
файл оказался в одном небольшом исходном файле на plugins/auth/old_password.c
.
казалось, что можно было бы изменить систему сборки (CMake), чтобы создать динамическую библиотеку для old_password
плагин. В источниках Connector/C есть cmake/plugins.cmake
файл, который действует как" реестр " для всех плагинов. Он содержит макро-х REGISTER_PLUGIN
что происходит STATIC
или . Эти функции называются другими функциями в ma_password.c
файл, поэтому я скопировал их. Опять же, это было только легко (или вариант вообще), так как ma_password.c
файл был таким простым. Если бы он сам имел зависимости или был более сложным, мне пришлось бы остановиться, бросить и изучить расширенный CMake-fu, чтобы решить проблему "правильным" способом. Я абсолютно уверен, что есть лучший способ сделать это.
(в сторону) в этот момент мне пришлось cron до регулярного запуска mysqladmin flush-hosts
на моем сервере БД, так как мое тестирование вызывало так много неудачных попыток, что мне пришлось это сделать часто. Возможно, есть и лучший способ обойти это, но я не знаю его, и я знаю крона.
с новыми - "встроенными" источниками,mysql_old_password.so
библиотека скомпилирована, я переименовал ее и снова запустил тестовый скрипт. На этот раз я получил:
pyodbc.Error: ('HY000', u'[HY000] [unixODBC][ma-3.0.2]Plugin old_password could not be loaded: name mismatch (2059) (SQLDriverConnect)')
я решил, что это как-то связано с тем, что я переименовал файл, чтобы ODBC мог его найти (он ищет old_password.so
не mysql_old_password.so
). Я попробовал подойти с ружьем. В plugins/auth/CMakeLists.txt
конфигурация системы сборки, I заменены все экземпляры mysql_old_password
с old_password
и составлен. Компиляция удалась, но все равно не сработала.
оказывается, что плагин сам по себе источник (old_password.c
в этом случае) имеют объявление структуры вверху, которое объявляет их имя, и это объявило свое имя как mysql_old_password
. Это вполне может быть уже существующей проблемой (т. е. это никогда не работало), и я начал чувствовать себя немного холодно: когда вы строите код, который чувствует, что его никто не построил или не протестировал в данной конфигурации перед, ваши шансы на успех не очень хорошо. Несмотря ни на что, я сделал то же самое s/mysql_old_password/old_password/
в исходном файле, а также скомпилированы. На этот раз он создал артефакт с правом old_password.so
имя. Я снова запустил тестовый скрипт и получил:
conn = pyodbc.connect('DRIVER={maria};Server=mysql;Database=mysql;User=admin;Password=admin;PLUGIN_DIR=/home/mysql/zclient/mdb-c/plugins/auth')
pyodbc.Error: ('HY000', u"[HY000] [unixODBC][ma-3.0.2]Access denied for user: 'admin@hostname' (Using password: NO) (1045) (SQLDriverConnect)")
это было странно. Я имел mysql
клиент командной строки, который поставляется с установленным сервером 3.23 (через tarball, а не в пути к системной библиотеке) на моем окне тестирования клиента, и он может нормально подключаться к ним учетные данные (я не мог проверить с isql
потому что я не мог заставить его правильно использовать PLUGIN_DIR
и не мог понять, где он хотел, чтобы я поставил плагины; это не было в системе shimming эти файлы, установив i386
архитектура и необходимые библиотеки. 64-разрядный Python/UnixODBC не удалось загрузить myodbc
Плагины успешно, возвращая общую ошибку" файл не найден", которую я в конечном итоге проследил до неудачного вызова dlopen
. Libtool не так dlopen
обертки (используемые UnixODBC) считаются не очень отладочными большинством людей, и после значительных хлопот мои рудиментарные трюки Valgrind, казалось, указывали, как я и ожидал, что невозможно динамически загружать архитектуру-несовместимую (i386
vs x86-64
) в ODBC базовая программа.
Решения / Оставшиеся Опции
в общем, вероятно, будет проще переписать код на вашем конце. Например, вы можете сделать модуль Python, который обертывает устаревший драйвер Python non-ODBC MySQL (как предложил @FlipperPA в комментариях к вопросу), взломать "достаточно"pyodbc
интерфейс на тот модуль, который вам не придется рефакторинг слишком много кода, который ее вызывает, и тщательное тестирование перед развертыванием. Я знаю это отстой и рискованно, но это, вероятно, ваш лучший выбор. При написании такого модуля вы можете использовать часть внутреннего кода в pyodbc
который обрабатывает общий синтаксис ODBC / и т. д.
вы даже можете разработать "поддельный" бэкэнд ODBC для pyodbc
, который только что вызвал драйвер MySQL не ODBC Python, но я подозреваю, что это будет сложно, так как pyodbc
бэкэнд-подключаемость, кажется, в первую очередь ориентирована на скомпилированные библиотеки, а не на "фиктивную" прокладку код.
я не эксперт в этом материале, так что вполне могут быть решения, которые я пропустил!
есть несколько других возможностей, которые я рассмотрел и отказался от:
вы можете подать ошибку с людьми MariaDB, и это может быть исправлено. У меня нет хорошего чувства, является ли ошибка протокола, с которой я закончил, "это принципиально несовместимо на каждом уровне" или "система auth просто нуждается в настройке, тогда все будет работать". Может, стоит попробовать.
поскольку есть 32-разрядные RPMs доступны версии 2.50 Connector/ODBC код (они не будут загружаться в 64-разрядную среду Python/UnixODBC), вы могли бы предположительно преобразовать весь стек (или даже дистрибутив операционной системы) в 32-разрядный код. Однако, если вы используете какой-либо не общий скомпилированный материал, это, вероятно, будет значительной проблемой. Хотя Ubuntu / Debian особенно хорош в создании пакетов, доступных на старых архитектурах, это все еще может будь хитрым. Даже если вы все преобразовали, некоторые поведения могут измениться, и старые 32-битные характеристики будут постоянной странностью для всех, кто работает над вашим приложением. И это только в том случае, если драйвер 2.50 работает при доступе из 32-разрядной среды выполнения; после этого могут возникнуть другие проблемы. Я бы рекомендовал попробовать это, только если нагрузка на обслуживание для всего вашего клиентского кода, вероятно, будет очень низкой в будущем (если проект мал или маловероятен изменение.)
мораль истории
программное обеспечение гниет кровавый быстро. Если проект не будет постоянно заниматься работой по поддержанию обратной совместимости, все быстро перестанет работать, особенно в веб-программном обеспечении.
дело не в том, что сам продукт ломается, а в том, что Вселенная меняется из-под него миллионом маленьких способов. Если только кто-то не достаточно универсален и не был достаточно долго, чтобы знать все эти небольшие изменения и как их отменить, очень сложно переместить все назад во времени/ревизии в место, где все "просто работает".
если вы получаете двоичные файлы для чего-то, даже если это что-то предположительно "общее", как драйвер MySQL,сохранить их. В идеале, поделитесь ими с интернетом.
если у вас есть источники для чего-то, строго документируйте весь список зависимостей/цепочек инструментов, которые им нужны, и документируйте его для человека. Предположим, что инструменты, необходимые для чтения списков программных зависимостей, например autotools, сами устареют. Ничто не является слишком "очевидным" для документирования; не архитектура, ядро ABI, поведение libc-ничего. Теперь, когда у нас есть" в коробке на любом ядре " такие вещи, как Docker, вы можете хранить больше своих зависимостей программным способом, но не рассчитывайте на это.
Как показал Zac B, нет реального способа подключить сервер MySQL 3.23 от клиента Ubuntu 16 с UnixODBC и pyodbc 3.07.
FlipperPA предложено использовать pypi.python.org/pypi/MySQL-python/1.2.4 следующее решение возможно. Поэтому я попробовал:
MySQL-python установлен через apt не удается подключиться к этому старому MySQL. Он использует системы mysql-client libs, которые не работают с MySQL 3.23.
MySQL-python установлен через Пип другое дело: он получает libs от mysql_config входит в libmysqlclient-dev пакета. Также не работает с MySQL 3.23. Но здесь есть шанс что-то изменить.
при установке libmariadb-клиент-lgpl-dev, Я mariadb_config который выглядит совсем как mysql_config. И mariadb-клиент Ubuntu 16 работал с MySQL 3.23 (как показано выше).
ln -s /usr/bin/mariadb_config mysql_config
pip install MySQL-python
это делает работу. Я могу подключить этот старый сервер MySQL от Python.
есть некоторые проблемы с типами данных, но я не требователен в этом случае.