Невозможно импортировать pyodbc на Mac

Я не могу импортировать pyodbc на свой Macbook Pro (работает под управлением Mac OS X 10.10.5) и python версии 2.7.10. Я использовал pip чтобы получить его, и у меня есть последняя версия (3.0.10). Это дает мне следующую ошибку:

 $ python Python 2.7.10 (default, Jul 14 2015, 19:46:27) [GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import pyodbc Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: dlopen(/Library/Python/2.7/site-packages/pyodbc.so, 2): Symbol not found: _SQLAllocHandle Referenced from: /Library/Python/2.7/site-packages/pyodbc.so Expected in: flat namespace in /Library/Python/2.7/site-packages/pyodbc.so 

Я пробовал несколько вещей в течение последних нескольких месяцев безрезультатно, в том числе и сам по себе (и (повторное) установление iodbc и unixodbc на этом пути).

Одна из странных вещей заключается в том, что ни один из других пакетов баз данных python, которые я пытался использовать (например, sqlalchemy, pypyodbc и т. Д.), Не работает ни по различным, ни по аналогичным причинам. Это заставило меня заподозрить некоторые основные проблемы с моим драйвером или библиотекой ODBC, но я не знаю, как его диагностировать.

Я работаю в среде общего кода, где остальная часть команды использует pyodbc через Windows, и мне действительно нужно, чтобы это работало сейчас. Любая помощь или предложения будут высоко оценены!


** Добавлено больше деталей в ответ на ответ mauro. Примечание. Второе обновление ниже меняет ситуацию. **

Вот еще несколько деталей, которые я должен был включить в исходный вопрос.

Во-первых, вот результаты команд, о которых спрашивали ману на моей машине.

 $ odbc_config --version 2.3.2 $ odbc_config --libs -L/usr/local/Cellar/unixodbc/2.3.2_1/lib -lodbc $ odbc_config --odbcini /usr/local/Cellar/unixodbc/2.3.2_1/etc/odbc.ini $ odbc_config --odbcinstini /usr/local/Cellar/unixodbc/2.3.2_1/etc/odbcinst.ini 

Я с подозрением относился к части «Подвала», поэтому я посмотрел на пути в ответе Мауро, и все они, похоже, указывают на «Подвал» (доморощенный?):

 $ ls -al /usr/local/etc/*odbc* lrwxr-xr-x 1 ***** admin 39 17 Aug 16:57 /usr/local/etc/odbc.ini@ -> ../Cellar/unixodbc/2.3.2_1/etc/odbc.ini lrwxr-xr-x 1 ***** admin 43 17 Aug 16:57 /usr/local/etc/odbcinst.ini@ -> ../Cellar/unixodbc/2.3.2_1/etc/odbcinst.ini $ ls -al /usr/local/etc/odbc* lrwxr-xr-x 1 ***** admin 39 17 Aug 16:57 /usr/local/etc/odbc.ini@ -> ../Cellar/unixodbc/2.3.2_1/etc/odbc.ini lrwxr-xr-x 1 ***** admin 43 17 Aug 16:57 /usr/local/etc/odbcinst.ini@ -> ../Cellar/unixodbc/2.3.2_1/etc/odbcinst.ini 1395:Stephens-BlueDot-MacBook-Pro:~/BlueDot/Code/Data Processing Tools} ls -al /usr/local/etc/*odbc* lrwxr-xr-x 1 ***** admin 39 17 Aug 16:57 /usr/local/etc/odbc.ini@ -> ../Cellar/unixodbc/2.3.2_1/etc/odbc.ini lrwxr-xr-x 1 ***** admin 43 17 Aug 16:57 /usr/local/etc/odbcinst.ini@ -> ../Cellar/unixodbc/2.3.2_1/etc/odbcinst.ini 1396:Stephens-BlueDot-MacBook-Pro:~/BlueDot/Code/Data Processing Tools} ls -al /usr/local/lib/*odbc* lrwxr-xr-x 1 ***** admin 46 17 Aug 16:57 /usr/local/lib/libodbc.2.dylib@ -> ../Cellar/unixodbc/2.3.2_1/lib/libodbc.2.dylib lrwxr-xr-x 1 ***** admin 44 17 Aug 16:57 /usr/local/lib/libodbc.dylib@ -> ../Cellar/unixodbc/2.3.2_1/lib/libodbc.dylib lrwxr-xr-x 1 ***** admin 48 17 Aug 16:57 /usr/local/lib/libodbccr.2.dylib@ -> ../Cellar/unixodbc/2.3.2_1/lib/libodbccr.2.dylib lrwxr-xr-x 1 ***** admin 46 17 Aug 16:57 /usr/local/lib/libodbccr.dylib@ -> ../Cellar/unixodbc/2.3.2_1/lib/libodbccr.dylib lrwxr-xr-x 1 ***** admin 50 17 Aug 16:57 /usr/local/lib/libodbcinst.2.dylib@ -> ../Cellar/unixodbc/2.3.2_1/lib/libodbcinst.2.dylib lrwxr-xr-x 1 ***** admin 48 17 Aug 16:57 /usr/local/lib/libodbcinst.dylib@ -> ../Cellar/unixodbc/2.3.2_1/lib/libodbcinst.dylib lrwxr-xr-x 1 ***** admin 45 17 Aug 16:59 /usr/local/lib/libtdsodbc.0.so@ -> ../Cellar/freetds/0.95.18/lib/libtdsodbc.0.so lrwxr-xr-x 1 ***** admin 42 17 Aug 16:59 /usr/local/lib/libtdsodbc.a@ -> ../Cellar/freetds/0.95.18/lib/libtdsodbc.a lrwxr-xr-x 1 ***** admin 43 17 Aug 16:59 /usr/local/lib/libtdsodbc.so@ -> ../Cellar/freetds/0.95.18/lib/libtdsodbc.so /usr/local/lib/tdbcodbc1.0.0: total 144 drwxr-xr-x 5 root wheel 170 29 Mar 2013 ./ drwxrwxr-x 44 root admin 1496 17 Aug 16:59 ../ -rwxr-xr-x 1 root wheel 49796 29 Mar 2013 libtdbcodbc1.0.0.dylib* -r--r--r-- 1 root wheel 245 29 Mar 2013 pkgIndex.tcl -r--r--r-- 1 root wheel 15624 29 Mar 2013 tdbcodbc.tcl 

Я могу подключиться к DNS через tsql (специфические анонимные):

 $ tsql -S servername.myserver.com -U me -P mypw -D testdb locale is "en_CA.UTF-8" locale charset is "UTF-8" using default charset "UTF-8" Setting testdb as default database in login packet 1> 

Но osql и isql дают проблемы:

 $ isql -v MyDSN me mypw [S1000][unixODBC][FreeTDS][SQL Server]Unable to connect to data source [01000][unixODBC][FreeTDS][SQL Server]Unknown host machine name. [ISQL]ERROR: Could not SQLConnect 

Это дает больше информации. Он находит запись DSN в моем файле ~/.odbc.ini по крайней мере.

 $ osql -S MyDSN -U ***** -P ***** checking shared odbc libraries linked to isql for default directories... /usr/local/bin/osql: line 53: ldd: command not found error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/strings: can't open file: (No such file or directory) osql: problem: no potential directory strings in "/usr/local/bin/isql" osql: advice: use "osql -I DIR" where DIR unixODBC\'s install prefix eg /usr/local isql strings are: checking odbc.ini files reading /Users/*****/.odbc.ini [MyDSN] found in /Users/*****/.odbc.ini found this section: [MyDSN] Description = testdb SQLServer DB Driver = FreeTDS Trace = Yes TraceFile = /tmp/sql.log Database = Places ServerName = ***** UserName = ***** Password = ***** Port = 1433 Protocol = 7.2 ReadOnly = No RowVersioning = No ShowSystemTables = No ShowOidColumn = No FakeOidIndex = No looking for driver for DSN [*****] in /Users/*****/.odbc.ini found driver line: " Driver = FreeTDS" driver "FreeTDS" found for [*****] in .odbc.ini found driver named "FreeTDS" "FreeTDS" is not an executable file looking for entry named [FreeTDS] in /odbcinst.ini grep: /odbcinst.ini: No such file or directory 

Я не уверен, как исправить проблемы, о которых сообщает isql , но это, по-видимому, указывает на то, что у меня что-то неправильно сконфигурировано для меня с odbc. К сожалению, мне жаль, что я не знаю / не помню точно, что я сделал, чтобы получить его таким образом. Я серьёзно пробовал разные вещи, связанные с этим, в течение нескольких недель.


Второе обновление после комментариев mauro.

Я немного продвинулся вперед. Я переустановил как unixODBC, так и freeTDS (прямо из http://www.unixodbc.org/ и http://www.freetds.org/ вместо использования homebrew), и после этого вывод моих команд odbc_config соответствовал odbc_config .

После некоторых игр с моими путями я смог получить оба osql и isql для успешного подключения к экземпляру SQL Server. (Я обнаружил одну причину, по которой это было неудачно раньше, потому что ИТ-отдел в моей организации блокировал весь трафик на порт 1433 в локальной сети. Когда я переключился на Wifi, как и мой сотрудник Windows, он работал.) Я считаю это большой прогресс!

Однако, когда я попытался снова импортировать pyodbc из python, я получил то же сообщение об ошибке, с которого я начал работать. Вздох. Поэтому любые другие идеи по-прежнему будут оценены!

2 Solutions collect form web for “Невозможно импортировать pyodbc на Mac”

Я согласен … самое первое, на что я могу ответить, это лежащий в основе слой ODBC.

Вы сказали, что вы установили unixODBC из источников на вашем Mac (например, я). Поэтому проверьте основные параметры unixODBC с помощью odbc_config (вы должны иметь его в /usr/local/bin ):

 $ odbc_config --version 2.3.4 $ odbc_config --libs -L/usr/local/lib -lodbc $ odbc_config --odbcini /usr/local/etc/odbc.ini $ odbc_config --odbcinstini /usr/local/etc/odbcinst.ini 

Затем, я думаю, вы создали источник данных для своей базы данных ODBC. Используйте другую утилиту unixODBC ( isql ), чтобы проверить, что вы можете подключиться к своей базе данных через ODBC:

 $ sql <your_DSN> <your_DB_user> <your_DB_password> -v +---------------------------------------+ | Connected! | | | | sql-statement | | help [tablename] | | quit | | | +---------------------------------------+ SQL> quit 

Если все в порядке, уровень unixODBC в порядке.

ОБНОВИТЬ

Хммм … вы получите это сообщение:

 ... checking odbc.ini files reading /Users/*****/.odbc.ini [MyDSN] found in /Users/*****/.odbc.ini ... 

но расположение odic.ini, сообщаемое unixODBC, отличается:

 $ odbc_config --odbcini /usr/local/Cellar/unixodbc/2.3.2_1/etc/odbc.ini 

Я бы также проверить, какие библиотеки используются pyodbc. Здесь у вас есть мои:

 $ otool -L /Library/Python/2.7/site-packages/pyodbc.so /Library/Python/2.7/site-packages/pyodbc.so: /usr/local/lib/libodbc.2.dylib (compatibility version 3.0.0, current version 3.0.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0) 

Как вы можете видеть, мой pyodbc использует libodbc, установленный в /usr/local/lib . Точно местоположение, указанное в моем случае odic_config.

ВТОРОЕ ОБНОВЛЕНИЕ

Хороший прогресс! Итак, чтобы подвести итог, текущий статус:

  1. isql DSN USER PASSWORD работает как ожидалось
  2. import pyodbc возвращает символ _SQLAllocHandle не найден. Это означает, что он не находит правильную библиотеку lib
  3. otool -L ...pyodbc.so (тот же путь, что и в 2.?) указывает на правильную lib

Если это так, я бы переустановил pyodbc (я использовал pip ). Я слышал, что у старой версии были проблемы с поиском правильных заголовков / библиотек. Теперь, когда isql работает … pyodbc также должен работать.

Во-первых, спасибо @mauro за его / ее полезные и постоянные предложения.

Спустя несколько месяцев, ударив головой о стены, вчера вечером я наконец смог заставить это работать!

Здесь я излагаю некоторые ключевые вещи (для меня) в надежде, что они могут быть полезны другим в том же самом затруднительном положении, что и я.

BG. Когда-то некоторое время назад (более месяца) я читал и пытался сделать то, что предлагалось здесь . Несмотря на то, что я не помню все, что я пытался, это привело меня к тому, что tsql работаю tsql а также, по-моему, с моими версиями unixODBC и freeTDS выпущены на freeTDS .

Начиная с того, что я задал вопрос выше, вот некоторые из вещей, которые я пробовал, которые, казалось, оказали влияние. (Я не уверен, какие вещи в особенности были самыми важными, поэтому я все рассказываю.) Точки 1 и 2 описаны выше, поэтому я не буду останавливаться на них.

I. Я повторно установил unixODBC и freeTDS со своих веб-сайтов проекта.

II. Я обнаружил, что порт 1433 заблокирован в моей локальной сети, поэтому я переключился на WiFi, где он не был заблокирован.

Эти две вещи привели к тому, что я смог получить isql и osql для работы.

III. Рассуждение о том, что pyodbc не смог импортировать в python из-за чего-то похожего на динамическую ошибку связывания. Я попытался загрузить /usr/local/lib/libodbc.dylib напрямую, используя как dl.open() и ctype.cdll.LoadLibrary() . В обоих случаях я получил сообщение об ошибке:

 dl.error: dlopen(libodbc.dylib, 6): no suitable image found. Did find: /usr/local/lib/libodbc.dylib: mach-o, but wrong architecture 

После некоторого копания, я привел меня перекомпилировать unixODBC для 32- вместо 64-бит следующим образом:

 sudo ./configure CFLAGS="-m32 -arch i386 -O2" LDFLAGS="-m32 -arch i386" CXXFLAGS="-m32 -arch i386" sudo make sudo make install 

В этот момент я смог явно загрузить libodbc.dylib с помощью dl.open() и, наконец, получить pyodbc для импорта!

Внутривенно К сожалению, без явной загрузки через dl.open() импорт по-прежнему не удался. Это заставило меня играть с моим LD_LIBRARY_PATH (как предлагается здесь ), но, похоже, ничего не работает. Поэтому я все еще застрял, используя dl.open() .

Кроме того, он все еще не работает, поскольку он не связан с драйвером freeTDS когда я пытался подключиться к источнику данных. Это, наконец, привело меня к следующему «рабочему» взлому:

 import sys if (sys.platform == 'darwin'): import dl _lib1 = dl.open("libodbc.dylib") # Found in /usr/local/lib _lib2 = dl.open("/opt/local/lib/libtdsodbc.so") import pyodbc 

Обратите внимание, что необходимо было использовать глобальные переменные _lib1 и _lib2 чтобы заставить его работать (я думаю, чтобы поддерживать загрузку материала).

На данный момент все, кажется, работает достаточно хорошо, и я могу использовать pyodbc !!


Было еще несколько вещей, которые я пробовал на этом пути, но мне непонятно, помогли они или нет.

  • Я также попытался скомпилировать freeTDS в 32-битном режиме, подобно тому, что я сделал для unixODBC , но я не уверен, что это сработало.

  • Я загрузил, построил и установил pyodbc из github repo в отличие от использования pip . (Это была та же самая версия – 3.0.10 – как и при поставках в комплекте).

  • За комментарий # 10 здесь я добавил две строки в darwin case setup.py в pyodbc загрузку pyodbc (ниже) и перезапустил python.py setup.py build install .

Подобно:

 elif sys.platform == 'darwin': # The latest versions of OS X no longer ship with iodbc. Assume # unixODBC for now. settings['libraries'].append('odbc') settings['include_dirs'] = ['/opt/local/include'] # Added this line settings['library_dirs'] = ['/opt/local/lib'] # Added this line # Python functions take a lot of 'char *' that really should be const. gcc complains about this *a lot* settings['extra_compile_args'].extend([ '-Wno-write-strings', '-Wno-deprecated-declarations' ]) # Apple has decided they won't maintain the iODBC system in OS/X and has added deprecation warnings in 10.8. # For now target 10.7 to eliminate the warnings. settings['define_macros'].append( ('MAC_OS_X_VERSION_10_7',) ) settings['include_dirs'] = ['/opt/local/include'] settings['library_dirs'] = ['/opt/local/lib'] 
  • После того, как я все закончил, я проверил, и я также смог импортировать и использовать pypyodbc без использования dl.open() . Я не уверен, что все эти шаги были необходимы для этого. Я подозреваю, что основной проблемой были 32-битные версии библиотек.

Наконец, хотя это не было связано с причинами, по которым я не мог получить pyodbc для импорта, я добавлю примечание о чем-то, что заставило меня потерять почти час. В какой-то момент я пытался выполнить (очень полезные) инструкции на этом сайте . Однако позже я обнаружил, что строка соединения, отличная от DSN, которую автор показал, не работает. Вместо этого я должен был использовать атрибуты соединения FreeTDS, показанные здесь, чтобы заставить работу работать. Например:

 "DRIVER=FreeTDS;Server=*****;Port=1433;TDS_Version=7.2;Database=*****;UID=*****;PWD=*****" 

Хотя в настоящее время все работает для меня по большей части, я должен упомянуть, что теперь я также иногда получаю следующую ошибку для некоторых моих курсоров запросов, но я не думаю, что это связано с любым из вышеперечисленных. (Вместо этого я подозреваю какой-то «тайм-аут» проблемы в соединении …)

  ... for row in cursor: File "/Library/Python/2.7/site-packages/pypyodbc.py", line 1920, in next row = self.fetchone() File "/Library/Python/2.7/site-packages/pypyodbc.py", line 1914, in fetchone check_success(self, ret) File "/Library/Python/2.7/site-packages/pypyodbc.py", line 986, in check_success ctrl_err(SQL_HANDLE_STMT, ODBC_obj.stmt_h, ret, ODBC_obj.ansi) File "/Library/Python/2.7/site-packages/pypyodbc.py", line 966, in ctrl_err raise DatabaseError(state,err_text) pypyodbc.DatabaseError: (u'08S01', u'[08S01] [FreeTDS][SQL Server]Bad token from the server: Datastream processing out of sync') Exception pypyodbc.DatabaseError: DatabaseError(u'08S01', u'[08S01] [FreeTDS][SQL Server]Write to the server failed') in <bound method Connection.__del__ of <pypyodbc.Connection instance at 0x60d5a8>> ignored 

В целом, я думаю, что было по крайней мере 3, если не 4, причины, по которым я не мог использовать pyodbc в python. Основные два были связаны с 32-битной компиляцией unixODBC и некоторой проблемой импорта библиотеки, которые я до сих пор не понимаю.

Удачи всем, кто должен провалить все это!

  • Передача выражения в качестве аргумента: ключевое слово не может быть выражением
  • Бесконечная ошибка цикла в Python
  • Как вызвать функцию в запущенном потоке Python
  • Случайный "pythonw.exe перестает работать" сбой
  • Для чего нужен тип буфера Python?
  • Как изменить интерпретатор Python, который использует gdb?
  • Ошибка: неверная команда 'bdist_egg'
  • Хранить данные SQLite 3 как переменную в Python
  • Как я могу получить список семейства шрифтов (или имя шрифта) в matplotlib
  • Метод Pythonic для суммирования всех нечетных строк в файле
  • Преобразование XLSX в CSV правильно с использованием python
  •  
    Interesting Posts for Van-Lav
    Python - лучший язык программирования в мире.