2015-11-14 3 views
1

Я пытаюсь подключиться к базе данных Sybase ASE 15 в окнах с использованием sqlalchemy (1.0.9) и pyobbc. Если я использую DNS URL все работает, как ожидалось:Sqlalchemy pyodbc DNS-less URL-строка соединения не работает

url = r'sybase+pyodbc://usename:[email protected]' 
engine = create_engine(url, echo=True) 
Session = sessionmaker(bind=engine) 
sess = Session() 
conn = sess.connection() 

Однако, если я избегаю DNS я получаю сообщение об ошибке:

url = 'sybase+pyodbc://username:[email protected]:port/database?driver=Adaptive Server Enterprise' 

, я получаю сообщение об ошибке:

DBAPIError: (pyodbc.Error) ('01S00', '[01S00] [SAP][ASE ODBC Driver]Invalid port number (30011) (SQLDriverConnect)')

Номер порта правильный, и это тот же порт, что указан в DNS.

Любые идеи?

ответ

2

Возможно, стоит попробовать работать с некоторой версией формата DSN-less, разделенного точкой с запятой, используемого pyODBC (и ODBC в целом). Некоторые примеры здесь:

http://www.connectionstrings.com/adaptive-server-enterprise-odbc-driver/

Этот вопрос решает подобную проблему с FreeTDS, но концепция та же, как строка соединения, в основном передается через к ODBC низкоуровневого подключения:

SqlAlchemy equivalent of pyodbc connect string using FreeTDS

URL-адрес анализируется до типа этого типа для окончательного соединения с помощью pyodbc через SQLDriverConnect (в ODBC API), поэтому непосредственное использование строки подключения ASE ODBC DSN-less может работать лучше.

Update: Ран быстрый тест, чтобы увидеть, что соединить аргументы производятся для этого URL:

from sqlalchemy.engine.url import * 
from sqlalchemy.connectors.pyodbc import * 

connector = PyODBCConnector() 
url = make_url("sybase+pyodbc://username:[email protected]:5555/database?driver=Adaptive Server Enterprise") 
print connector.create_connect_args(url) 

Это приводит к:

[['DRIVER={Adaptive Server Enterprise};Server=host,5555;Database=database;UID=username;PWD=password'], {}] 

Обратите внимание, что имя хоста и порт отделены друг от друга запятая, за http://www.connectionstrings.com/adaptive-server-enterprise-odbc-driver/tds-based-odbc-driver-from-sybase-ocs-125/, этот формат работает для ODBC на основе TDS для Sybase 12.5:

Driver={Sybase ASE ODBC Driver};NetworkAddress=myServerAddress,5000; 
Db=myDataBase;Uid=myUsername;Pwd=myPassword; 

Однако формат ASE 15 (http://www.connectionstrings.com/adaptive-server-enterprise-odbc-driver/adaptive-server-enterprise-150/) определяет server=myServerAddress;port=myPortnumber с port как ключ передается в строке точку с запятой:

Driver={Adaptive Server Enterprise};app=myAppName;server=myServerAddress; 
port=myPortnumber;db=myDataBase;uid=myUsername;pwd=myPassword; 

Если вы «обмануть» на спецификации порта с помощью host;port=5555, вы получите:

[['DRIVER={Adaptive Server Enterprise};Server=host;port=5555;Database=database;UID=username;PWD=password'], {}] 

Но это похоже на Bad Idea ™, даже если оно работает. Я также хотел бы отметить, что сгенерированная строка использует Database в качестве ключа против Db в ссылке на строку Sybase. Это может оказаться проблемой.

Использование ?odbc_connect как в связанном вопросе, вероятно, является вашим лучшим вариантом для управления точными аргументами подключения, отправляемыми в ODBC.

+0

Thanks @will. Пойдем к более подробному просмотру/тестированию позже сегодня днем. Немного раздражает, так как не так чисто и код становится менее общим. С особой обработкой для Sybase.Что вы думаете о методе Творца, предложенном в вопросе, который вы приложили? – user2579685

+0

Будет использовать первый метод, который вы предлагаете (Плохая идея!). Второй, похоже, не работал. Я мог бы также удалить порт из строки и сделать следующее: connect_args = {'port': port} engine = create_engine (url, echo = False, connect_args = connect_args) – user2579685

+0

Это кажется разумным. –

Смежные вопросы