Не удается импортировать 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.
ВТОРОЕ ОБНОВЛЕНИЕ
хороший прогресс! Итак, подводя итог, текущий статус:
-
isql DSN USER PASSWORD
работает -
import pyodbc
возвращает символ _SQLAllocHandle не найден. Это означает, что он не находит правильный lib -
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
и некоторые проблемы с импортом библиотеки, которые я все еще не понимаю.
удачи всем, кто должен пройти через все это!