We wanted to move our Pylons application from Windows to Linux (hosted on Westhost), and still connect to our MS SQL database out there. It’d be simpler and faster to use a local MySQL also hosted on Westhost, perhaps, but that’ll come later.
SQLAlchemy (that we’re using in Pylons for database access) will work with PyMSSQL, PyODBC, and adodbapi. We’re using PyODBC (because PyMSSQL couldn’t connect with integrated security, and didn’t look into adodbapi.)
UnixODBC is a “Driver Manager.” This must be built first.
Easysoft has an “ODBC-SQL Server Driver” ($$). FreeTDS is an alternative Driver. One of these is built next.
PyODBC is the Python-specific part, and must be built against a driver manager (unixODBC). This is built last.
We’re using SQL Server 2005, so we need TDS Version 8.0.
Problem: Couldn’t get jsonlib installed on Westhost (easy_install didn’t support https), so we switched to simplejson. Not too hard except that we needed to support “ordered dictionaries” so that json output would be in the same order as we put items in a hash {’a':1,’b':2} for example. Doesn’t really matter but it makes life easier when debugging or reading json. We updated to simplejson 1.9.1 along the way, and had to update the python path in .htaccess mod_python set-up, which is now in /etc/httpd/conf/httpd.conf.
Problem: Apache/mod_python couldn’t import pyodbc. The problem was environment variable LD_LIBRARY_PATH which didn’t seem to include /usr/local/lib. You can’t set this from within Python so you must put it in /etc/ld.so.conf — hey, it was already there! Then you do ldconfig. This fixed the problem.
Problem: Couldn’t get “whole thing” (access database from SQL Alchemy) working, so needed to break apart and test each part freetds/unixodbc/pyodbc/sqlAlchemy separately. Fortunately, you can test just freetds, without using /usr/local/etc/freetds.conf by doing tsql -H mydbhost.com -p 1433 -U myuser -P mypasswd, and when you get that working, edit your freetds.conf to put in a server. You should set up a trace file in the [global] section (but be sure to remove it before running any serious traffic!) dump file = stdout will be useful. Add lines like[myServer]
host = mydbhost.com
port = 1433
tds version = 8.0
Now you can test using tsql -S myServer -U user -P passwd (omit -H -p). This tests what’s in freetds.conf.
Next test with isql which uses unixODBC. You can edit /usr/local/etc/odbcinst.ini to put in
[TDS]
Description = FreeTDS Driver
Driver = /usr/local/lib/libtdsodbc.so
Setup=/usr/local/lib/libtdsS.so
UsageCount = 1
And in odbc.ini, create a DSN (you don’t actually need to use DSN’s but that’s what I did.)[MyDSN]
Description=my dsn
Driver=TDS
Database=yourdb
Servername=myServer
Do NOT start any lines in odbc.ini with spaces — cost me a few hours!
Now on to pyodbc. You can test with:
$ python
import pyodbc
cnxn = pyodbc.connect("DSN=MyDSN;UID=user;PWD=pwd")
cursor = cnxn.cursor()
cursor.execute("select 2+2 as [Result]")
for row in cursor:
print row.Result
And finally to test SQL Alchemy:
$ python
import sqlalchemy as sa
eng = sa.create_engine("mssql://usernm:pwd@/?dsn=MyDSN",echo=True)
res = eng.execute('select 1+1 as foo')
for row in res:
print 'answer=',row['foo']
You might want to do some of these tests within the Apache/mod_python context The main problems I had along those lines were Python’s path (solved in earlier post in .htaccess or in httpd.conf) and LD_LIBRARY_PATH solved above.
New problem: Doing an update works in isql but fails in sqlalchemy, saying there is a datatype incompatibility (updating int with varchar).
Summary of free software layers we’re using in this project:
pylons (mako, sqlalchemy, simplejson), dojo, python, apache, mod_python, pyodbc, simplejson, unixODBC, freetds. Probably a dozen more I’ll remember later! We’re using Wing IDE Pro ($$) for editing under Windows, and vim for editing on westhost.