Не удается импортировать 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 через окна и я действительно нужно, чтобы это работало сейчас. Любая помощь или предложения будут высоко ценится!


**добавлено более подробности в ответ на ответ Мауро. Примечание, второе обновление ниже изменяет вещи. **

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

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

$ 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 в my по крайней мере.

$ 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 e.g. /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. К сожалению, мне жаль, что я не знаю / помню точно, что я сделал поймите это так - я серьезно пробовал различные вещи, связанные с этим, в течение нескольких недель.


второе обновление после комментариев Мауро.

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

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

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

2 ответов


Я согласен... самое первое, что нужно проверить, на мой взгляд, это базовый слой 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
...

но одическая.местоположение 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.?) право Либ

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


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

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

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

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

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

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

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

III. Рассуждая, что pyodbc не удалось импортировать в python из-за чего-то похожего на ошибку динамической компоновки. Я попытался загрузить /usr/local/lib/libodbc.dylib напрямую через оба!--15--> и 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

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

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

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

IV. К сожалению, без явной загрузки через 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 РЕПО в отличие от использования pip. (Это была та же версия-3.0.10-как pip хотя припасы.)

  • за комментарий #10 здесь, я добавил две строки darwin случае setup.py на 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 - и 64-битные версии библиотек.

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

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

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

  ...
    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 - и 64-разрядной компиляции unixODBC и некоторые проблемы с импортом библиотеки, которые я все еще не понимаю.

удачи всем, кто должен пройти через все это!