The following works:
import pyodbc
pyodbc.connect('DRIVER={FreeTDS};Server=my.db.server;Database=mydb;UID=myuser;PWD=mypwd;TDS_Version=8.0;Port=1433;')
The following fails:
import sqlalchemy
sqlalchemy.create_engine("mssql://myuser:mypwd@my.db.server:1433/mydb?driver=FreeTDS& odbc_options='TDS_Version=8.0'").connect()
The error message for above is:
DBAPIError: (Error) ('08001', '[08001] [unixODBC][FreeTDS][SQL Server]Unable to connect to data source (0) (SQLDriverConnectW)') None None
Can someone please point me in the right direction? Is there a way I can simply tell sqlalchemy to pass a specific connect string through to pyodbc?
Please Note: I want to keep this DSN-less.
This works:
In that format, SQLAlchemy just ignores the connection string and passes it straight on to pyodbc.
Update:
Sorry, I forgot that the uri has to be url-encoded, therefore, the following works:
The example by @Singletoned would not work for me with SQLAlchemy 0.7.2. From the SQLAlchemy docs for connecting to SQL Server:
If you require a connection string that is outside the options presented above, use the odbc_connect keyword to pass in a urlencoded connection string. What gets passed in will be urldecoded and passed directly.
So to make it work I used:
This should apply to Sybase as well.
NOTE: In python 3 the urllib module has been split into parts and renamed. Thus, this line in python 2.7:
has to be changed to this line in python3:
Internally "my.db.server:1433" is passed as part of a connection string like
SERVER=my.db.server:1433;
.Unfortunately unixODBC/FreeTDS won't accept a port in the SERVER bit. Instead it wants
SERVER=my.db.server;PORT=1433;
To use the sqlalchemy syntax for a connection string, you must specify the port as a parameter.
becomes:
I'm still interested in a way to do this in one line within the sqlalchemy
create_engine
statement, but I found the following workaround detailed here:UPDATE: Addresses a concern I raised in my own comment about not being able to pass arguments to the connect string. The following is a general solution if you need to dynamically connect to different databases at runtime. I only pass the database name as a parameter, but additional parameters could easily be used as needed:
To pass various parameters to your connect function, it sounds like format string might do what you want:
And you would then call it with something like:
More info on format strings is here: http://docs.python.org/library/string.html#formatstrings