<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Singletoned &#187; linux</title>
	<atom:link href="http://blog.singletoned.net/tag/linux/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.singletoned.net</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Thu, 21 Jan 2010 20:50:16 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Connecting to MS SQL Server from Python on Linux</title>
		<link>http://blog.singletoned.net/2009/07/connecting-to-ms-sql-server-from-python-on-linux/</link>
		<comments>http://blog.singletoned.net/2009/07/connecting-to-ms-sql-server-from-python-on-linux/#comments</comments>
		<pubDate>Thu, 30 Jul 2009 11:28:54 +0000</pubDate>
		<dc:creator>Ed Singleton</dc:creator>
				<category><![CDATA[howto]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[freetds]]></category>
		<category><![CDATA[sqlalchemy]]></category>
		<category><![CDATA[unixodbc]]></category>

		<guid isPermaLink="false">http://blog.singletoned.net/?p=24</guid>
		<description><![CDATA[This is the follow up to my post on connecting Python to SQL Server on
Mac.  This describes how I set it up on Linux.

Quite a few bits of it are copied from the Mac instructions, so it
might be a little repetetive if you&#8217;ve already read that.  (No new
jokes, I&#8217;m afraid).

Edit: I&#8217;ve updated this [...]]]></description>
			<content:encoded><![CDATA[<p>This is the follow up to my post on connecting Python to SQL Server on
Mac.  This describes how I set it up on Linux.</p>

<p>Quite a few bits of it are copied from the Mac instructions, so it
might be a little repetetive if you&#8217;ve already read that.  (No new
jokes, I&#8217;m afraid).</p>

<p><em>Edit</em>: I&#8217;ve updated this having tried the installation a few more
times.  I&#8217;m still not 100% sure, but I appear to have got it working
several times in a row.</p>

<h1>Summary</h1>

<ul>
<li>Install unixodbc and unixodbc-dev</li>
<li>Install the patched version of freetds</li>
<li>Install tdsodbc</li>
<li>Install the patched version of freetds again</li>
<li>Configure unixodbc</li>
<li>Install python</li>
<li>Install sqlalchemy and pyodbc</li>
</ul>

<h1>Installing freetds on Linux</h1>

<p>I&#8217;m basing this on a bare bones install of Debian Lenny (ie starting
with the bare minimum you can install).</p>

<p>I initially setup sudo, git, svn, bzr, openssh and emacs22.  I won&#8217;t
go too much into them here.  You might use different tools.  I did
place my <code>/etc</code> and <code>/home</code> under version control with git as soon as
possible, which I highly recommend for experimental setups.  I
regret not putting <code>/usr</code> under version control as well.</p>

<p>At some point you will need the tools to compile source such as
python2.6 and pyodbc.  You might as well install them now.</p>

<pre><code>sudo aptitude install build-essential
</code></pre>

<p>I also recommend installing <code>checkinstall</code> which allows you to install
from source as if it were a proper debian package.  This allows you to
meet dependencies with it and remove it easily at a later date.</p>

<pre><code> sudo aptitude install checkinstall
</code></pre>

<p>Next you&#8217;ll need to install unixodbc.  You&#8217;ll also need
the unixodbc dev headers for later (eg compiling pyodbc).</p>

<pre><code>sudo aptitude install unixodbc, unixodbc-dev
</code></pre>

<p>Then you need to install the patched version of <code>freetds</code>.  I pass two
options to configure which make it work better with SQL Server, but
might stop it working as well with Sybase and others.  I don&#8217;t really
care about that at the moment, but bear it in mind.</p>

<pre><code>mkdir src
cd src/
wget ftp://ftp.ibiblio.org/pub/Linux/ALPHA/freetds/stable/freetds-patched.tgz
tar zxvf freetds-patched.tgz
cd freetds-0.82.1.dev.20090618/
./configure --enable-msdblib  --with-tdsver=8.0
make
sudo checkinstall
# When asked edit the 'provides' (11) value to be 'freetds-common'
# This allows it to be used as a dependency for tdsodbc
</code></pre>

<p>Now install <code>tdsodbc</code>:</p>

<pre><code>sudo aptitude install tdsodbc
</code></pre>

<p>Then install <code>tdsodbc</code> again:</p>

<pre><code>cd src/freetds-0.82.1.dev.20090618/
sudo make clean
./configure --enable-msdblib  --with-tdsver=8.0
make
sudo checkinstall
# When asked edit the 'provides' (11) value to be 'freetds-common'
</code></pre>

<p>I&#8217;m not entirely sure about this, but it appears to work for me.  It
doesn&#8217;t entirely make sense though, so I suspect that there is
something better that can be done here.</p>

<p>Now you&#8217;re ready to setup up your odbc drivers and data sources.</p>

<p>You&#8217;ll need to create two files, <code>tds.driver.template</code> and
<code>tds.dsn.template</code>.  It doesn&#8217;t really matter where you create them,
as they are templates to create your <code>odbcinst.ini</code> and <code>odbc.ini</code>
files, but it&#8217;s worth putting them somewhere safe so that you can
refer back to them later.</p>

<pre><code>touch tds.driver.template
touch tds.dsn.template
</code></pre>

<p>Edit them and add the following, adjusted for your servername, dbname etc.</p>

<pre><code># tds.driver.template
[TDS]
Description     = FreeTDS Driver for Linux &amp; MSSQL on Win32
Driver          = /usr/lib/odbc/libtdsodbc.so
Setup           = /usr/lib/odbc/libtdsS.so

# tds.dsn.template
[my_dsn]
Description     = Connection to windows virtual machine
Driver          = TDS
Trace           = No
Database        = my_database_name
Server          = MY-SERVER
Port            = 1433
TDS_Version     = 8.0
</code></pre>

<p>Note that in the driver template you are naming a driver.  You then
use that name in the dsn template as the value of the driver.  This
can be any name you want instead of <code>TDS</code>, but they must match.
Alternatively, you can specify the path to the driver in the dsn
template.</p>

<p>Now you are ready to install the two templates.  You&#8217;ll need to run
<code>odbcinst</code> for each template.  Running <code>odbcinst</code> without any
arguments will give you some useful info, but I&#8217;ll summarise what you
need to know to get it working.</p>

<pre><code> sudo odbcinst -i -d -f tds.driver.template
 # -i says you want to install
 # -d says you are installing the driver
 # -f says what template you are using

 sudo odbcinst -i -s -l -f tds.dsn.template
 # -i says you want to install
 # -s says you want to install dsn
 # -l says you want to install system dsn
 # -f says what template you are using
</code></pre>

<p>These will copy the contents of the templates to <code>/etc/odbcinst.ini</code>
and <code>/etc/odbc.ini</code> respectively.  They also perform some piece of
magic that I haven&#8217;t worked out yet (eg. if you duplicate the entry it
adds to <code>odbc.ini</code> and change the name slightly, it doesn&#8217;t seem to
work).  However adding a new entry using <code>odbcinst</code> does work.</p>

<p>With the second call to <code>odbcinst</code>, you have a choice between
installing system dsn to <code>/etc/odbc.ini</code> using <code>-l</code> or user
dsn in <code>~/.odbc</code> using <code>-h</code>.  I recommend system dsn for development,
and doing more research for production.</p>

<p>Don&#8217;t forget that you might have to add your db-server to your hosts
file, depending on your network setup.  Just edit <code>/etc/hosts</code> and add
the ip address and name of your server underneath the entry for
localhost.</p>

<p>Now you should be able to run queries on your database, using <code>isql</code>.</p>

<pre><code>isql my_dsn username password
</code></pre>

<p>This should bring up an SQL prompt that allows you to execute queries
on the server.  Try a couple of queries to test it.  If you don&#8217;t have
a legacy database with data already in it, why the hell are you using
SQL Server?</p>

<h1>Connecting Python to SQL Server through pyodbc and freetds on Linux</h1>

<p>You should now be ready to get python sorted out.  If you&#8217;ve had any
problems so far, let me know and I&#8217;ll try to help.</p>

<p>First, you need a python installed.  I&#8217;ve installed 2.6 from source,
which I&#8217;ll briefly cover, but you should also be able to use the
python2.5 package that&#8217;s available.</p>

<p>In order to have all the functionality of python when installing from
source, you will need some extra libraries:</p>

<pre><code>sudo aptitude install libncursesw5-dev libreadline5-dev libssl-dev \
libgdbm-dev libbz2-dev libc6-dev libsqlite3-dev libdb-dev tk-dev
# That's all on one line, not two
</code></pre>

<p>I&#8217;ve used <code>checkinstall</code> to install python as a package.
Alternatively you can install it to your home folder by passing
<code>--prefix=/home/username</code> to configure.</p>

<p>To install it to your home folder, just download the source from the
python website, unzip it, configure it, then use <code>checkinstall</code>.</p>

<pre><code>wget http://www.python.org/ftp/python/2.6.2/Python-2.6.2.tgz
tar zxvf Python-2.6.2.tgz 
cd Python-2.6.2/
./configure
make
sudo checkinstall
</code></pre>

<p>I also strongly recommend using virtualenv and virtualenvwrapper.
Create a virtualenv as soon as you have installed python and always
create your other virtualenvs from that, so that you can easily get
back to a clean python if you need to.  (I&#8217;ll add instructions for
that as a seperate post sometime).  Install <code>pyodbc</code> into your
virtualenv:</p>

<pre><code>    easy_install pyodbc
</code></pre>

<p>If you installed the <code>build-essential</code> and <code>unixodbc-dev</code> earlier you
should have what you need to compile it.</p>

<p>Now checkout the 0.6 branch of SQLAlchemy.  This is currently a branch
but should soon move to trunk.  It&#8217;s fine for development.  If you are
using this as a guide to setting up your production server, you are
insane.</p>

<pre><code>svn checkout http://svn.sqlalchemy.org/sqlalchemy/branches/rel_0_6
# Make sure your virtualenv is activated then:
cd rel_0_6
python setup.py develop
</code></pre>

<p>You should now be able to run some basic tests using SQLAlchemy:</p>

<pre><code>&gt;&gt;&gt; import sqlalchemy as sa
&gt;&gt;&gt; uri = "mssql://username:password@my_dsn"
&gt;&gt;&gt; engine = sa.create_engine(uri)
&gt;&gt;&gt; select_query = sa.text("SELECT * FROM MyTable")
&gt;&gt;&gt; result = engine.execute(select_query)
&gt;&gt;&gt; result.fetchall()
[]
&gt;&gt;&gt; insert_query = sa.text(
    "INSERT INTO MyTable (id, text_field) VALUES (:id, :text_field)")
&gt;&gt;&gt; result = engine.execute(insert_query, 
        id="Brian", text_field="Naughty Boy")
&gt;&gt;&gt; result = engine.execute(select_query)
&gt;&gt;&gt; result.fetchall()
[('Brian', 'Naughty Boy')]
</code></pre>

<p>That should all work.  At this point you should probably try running
some other tests.  Particularly ones involving non-ascii chars.  Then
you can watch it crumble and die.  (Actually if you&#8217;ve installed it
correctly, it should work with non-ascii chars).</p>

<p>The UK Pound Sign (£) is a particularly good symbol to use for testing
as it has a different byte representation between latin-1 and utf-8.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.singletoned.net/2009/07/connecting-to-ms-sql-server-from-python-on-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
