There are a lot of hoops to jump through. Will's answer outlines a good number of them.
After much struggle, I managed to get this working with Docker (so this should work anywhere that runs docker).
I have tested the setup with Python 3.6 and Python 2.7: with pyodbc==3.0.10, django-pyodbc-azure and Django 1.10.4 (this setup is for Django, but works for vanilla python as well).
I've created a public image which you can use: https://hub.docker.com/r/toast38coza/python-mssql/
Here is a simple working docker setup:
version: "3"
services:
db:
restart: on-failure:10
image: microsoft/mssql-server-linux:latest
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=SuperSecret(!)100
ports:
- "1433:1433"
py:
image: toast38coza/python-mssql
links:
- db
environment:
- SA_PASSWORD=SuperSecret(!)100
- DB_NAME=mydb
Now you can run:
docker-compose run --rm py python
Which will run the python cli inside the py service above
Then try create a database:
>>> import pyodbc, os
>>> db_name = os.environ.get('DB_NAME')
>>> pwd = os.environ.get('SA_PASSWORD')
>>> connection_string = "driver=FreeTDS;server=db;PORT=1433 database=master;UID=sa;PWD={};TDS_Version=8.0;".format(pwd)
>>> conn = pyodbc.connect(connection_string, autocommit=True)
>>> conn.execute('create database {}'.format(db_name))
<pyodbc.Cursor object at 0x7fb3067f0e70>
That should create a database called mydb (the DB_NAME from the docker-compose file environment variable). Note: because we've created the link to the db service (running MS SQL), we can use the hostname db. If you are connecting to an external MS SQL setup, you obviously don't need the db service (and edit your connection string accordingly)
If you're using Django, there is a more complete example in the repo, but, just a heads up, you will need your settings to look something like this:
DATABASES = {
'default': {
'ENGINE': "sql_server.pyodbc",
'HOST': "db",
'PORT':'1433',
'USER': "sa",
'PASSWORD': os.environ.get('SA_PASSWORD'),
'NAME': os.environ.get('DB_NAME'),
'OPTIONS': {
"driver": "FreeTDS",
"host_is_server": True,
"unicode_results": True,
"extra_params": "tds_version=8.0",
}
}
}