January 14th, 2010
For a while I have been getting the following error whenever I tried to retrieve an instance of a django model which had a field that used a column of type ntext:
ProgrammingError: (‘42000′, ‘[42000] [FreeTDS][SQL Server]Unicode data in a Unicode-only collation or ntext data cannot be sent to clients using DB-Library (such as ISQL) or ODBC version 3.7 or earlier. (4004) (SQLExecDirectW)’)
Every time I run into this problem I looked for ways around it, and for the most part I was always able to find one which is why I never had to try to find a solution to the actual problem. When I had to do something for which I couldn’t find a way around it, I had to look for a solution and I almost gave up after reading hundreds of pages. Thankfully I was able to find a solution here it is in case you find it useful.
The problem was due to the fact that I was using TDS version 4.2, the default version, when connecting to a MS SQL 2008 DB when I needed to use TDS version 8.0. Go here for a more in depth explanation of how to choose the right TDS version: http://www.freetds.org/userguide/choosingtdsprotocol.htm
In order to find out what TDS version I was using I followed the steps outlined here: http://www.freetds.org/userguide/logging.htm
After I knew for sure I was using the wrong TDS version I updated my vi /etc/freetds/freetds.conf file to include the following line:
tds version = 8.0
But I kept getting the same problem, I then found that I needed to update my odbc.ini file to include the following line when using FREETDS through unixODBC:
tds version = 8.0
But I kep getting the same problem. It was pretty weird to me that the .ini file would accept a property with a space in it but pretty much every document I read had it like that until I run into this document which replaced the space with an underscore, so I changed the odbc line to look like:
tds_version = 8.0
I tried again, and I no longer got an error. The bottom line is that you need to use the TDS version that is appropriate to the MSSQL server you are trying to connect to and that in order to tell unixODBC, which is what pyODBC uses, what TDS version to use, you need to add the line above in your odbc.ini file.
The following is a list of pages that have good info about FREETDS and unixODBC:
- http://www.freetds.org/userguide/choosingtdsprotocol.htm
- http://www.freetds.org/userguide/logging.htm
- http://lucasmanual.com/mywiki/unixODBC
- http://kipb7.wordpress.com/2008/06/12/pyodbc-unixodbc-freetds-config/ (This page explains how to test the configuration of FREETDS and unixODBC)
- http://www.freetds.org/userguide/freetdsconf.htm#TAB.FREETDS.CONF.DEBUGFLAGS
Posted in | No Comments »
July 9th, 2009
I work as a project manager for a company that uses almost exclusively Microsoft technology. This means that all our sites are created using .Net and they use MS SQL.
We are a very small company but we have tons of projects. A request for an automatic report recently came up but all of my .Net developers were busy and I knew the report would be very easy to do if the sites were powered by Django so I decided to see if I could use Python on Django to create the report. The only problem was how to connect to the MS SQL DB from a Linux machine using Django. The following are the steps I took to overcome that problem.
The following steps have been tested on Ubuntu Jaunty and using Django’s latest development version. If you need help installing Django go here http://docs.djangoproject.com/en/dev/topics/install/#installing-development-version
- Download and install tdsodbc, unixODBC, g++ and python-dev(sudo aptitude install odsodbc unixODBC python-dev g++)
- Download pyodbc
- Build pyodbc by running the following command within the folder where you stored the downloaded pyodbc code:sudo python setup.py build
- Install pydobc by running:sudo python setup.py installYou can test the installation of pydobc by running a python shell and trying to import the pyodbc module(import pyodbc). If you get an error, pyodbc was not installed correctly.
- Check out the latest pyodbc code from here(http://code.google.com/p/django-pyodbc/source/checkout)
- Create a symbolic link on your system’s site-packages folder to where you stored the djang-odbc code. You can find out the site-packagess folder for your system by running:python -c “from distutils.sysconfig import get_python_lib; print get_python_lib()”.
- Test that the python interpreter can load django-pyodbc by running a python shell and executing the following “import sql_server”
- Now we need to create an ODBC DSN for the database you are trying to connect to. Using you favorite editor open the file /etc/odbc.ini and add the following:[MSSQL-PYTHON]
Driver = /usr/lib/odbc/libtdsodbc.so
Server = [Connection String to DB. eg: 127.0.0.1\SQLEXPRESS]
- On the settings.py file of the django project you need the following:DATABASE_ENGINE = ’sql_server.pyodbc’
DATABASE_NAME = ‘DB_Name’
DATABASE_USER = ‘user_name’
DATABASE_PASSWORD =’DB_password’
DATABASE_OPTIONS = {
‘driver’: ‘FreeTDS’,
‘dsn’: ‘MSSQL-PYTHON’, # ODBC DSN name defined in your odbc.ini
}
- You are done!
I will write another post explaining how I coded my models to work with the existing tables, specially to handle manyTomany relationships
Posted in | 3 Comments »
January 10th, 2009
For the code at the bottom of page 69 to work you need to make sure you have you are import the coltrane Entry model in the urls.py file of the cms app which you should have created in the previous chapter.
Tags: django, errata
Posted in Practical Django Projects | No Comments »
January 8th, 2009
The import command will not work because whoever packaged this application forgot to add the file __init__.py which is what tells python that the folder should be treated as a module. After you add an empty file named __init__.py everything should work as expected.
Also the following 2 lines of code are incorrect:
self.body_html = markdown(self.body)
self.excerpt_html = markdown(self.excerpt)
The problem is that the folder module is called markdown, and then the file that contains the class is called markdown, and the class we need is called Markdown, notice capital M.
Assuming we want to use the import statement as specified in the book, the 2 lines of code above need be changed to:
self.body_html = markdown.Markdown(self.body).convert()
self.excerpt_html = markdown.Markdown(self.excerpt).convert()
Tags: django, errata
Posted in Practical Django Projects | No Comments »
January 8th, 2009
The code on these pages will obviously not work as is. If you don’t know why, please read my previous posts.
I will not post how the code should look like, as you should have the correct code if you have been following the posts.
Tags: django, errata
Posted in Practical Django Projects | No Comments »
January 8th, 2009
The prepopulate_attribute should be removed from the definition of the slug fields. That option should be in the admin class of the model. See previous posts to know more.
Tags: django, errata
Posted in Practical Django Projects | No Comments »
January 8th, 2009
The following line of code is no longer correct:
slug = models.SlugField(prepopulate_form=['title'],unique=True)
Because the prepopulate_form attribute is something that only has meaning within the admin app, it now has to be put in the admin.py file. Assuming you have read the previous post, the content of admin.py should be the following:
from django.contrib import admin
from coltrane.models import Category
class CategoryAdmin(admin.ModelAdmin):
model = Category
prepopulated_fields = {
"slug" : ("title",)
}
admin.site.register(Category,CategoryAdmin)
Tags: django, errata
Posted in Practical Django Projects | No Comments »
January 8th, 2009
The Category model is using the old way of telling the admin app to include it in the admin section. Read this to know more.
If you have read the previous posts you should be able to know by now what is wrong and how to correct it. But in case you don’t, here is what you need to change to make it work:
1. Delete the following 2 lines:
class Admin:
pass
2. Go to the folder where you added the models.py file(If you are following the book verbatim it should be named coltrane), create a file called admin.py and the following code to it:
from django.contrib import admin
from coltrane.models import Category
admin.site.register(Category)
Spoiler: You will have to change the code above to include other options before the chapter is over
Tags: django, errata
Posted in Practical Django Projects | 1 Comment »
January 5th, 2009
For this post to make sense you should read this first.
First of all ignore the updated code on this page, and leave the search/models.py the way it looked before this page. Bellow is how it should look in case it helps:
from django.db import models
from django.contrib.flatpages.models import FlatPage
class SearchKeyword(models.Model):
keyword = models.CharField(max_length=50)
page = models.ForeignKey(FlatPage)
def __unicode__(self):
return self.keyword
Open up the admin.py file and change it so that it looks like this:
from cms.search.models import SearchKeyword
from django.contrib import admin
from django.contrib.flatpages.admin import FlatPageAdmin
from django.contrib.flatpages.models import FlatPage
class SearchKeywordInline(admin.StackedInline):
model=SearchKeyword
extra=3
FlatPageAdmin.inlines=[SearchKeywordInline]
admin.site.unregister(FlatPage)
admin.site.register(FlatPage, FlatPageAdmin)
As you can see, now there classes for the different inline admin views(StackedInline and TabularInline) and all you need to do is create a new class that extends from one those for the model you want. One of the tricky things was to find out how to change the way the FlatPage model, which is a contributed app, is shown on the admin section. I believe the best way to do is to add the inline property to it and re-register the Admin Model of it so that the changes are picked up.
I would recommend you read this to get more familiar with the way the admin app works.
Posted in | No Comments »
January 4th, 2009
The code for the model SearchKeyword, which is just introduced on page 34, needs to be changed to account for the decoupling of model and admin definitation that happened on Django 1.0.
Eventhough it was very easy before, Django 1.0, to tell the admin app that you wanted it to generate an admin interface for a model it was pretty ugly. The new way takes a couple more steps at the beginning but I believe in the long run it has a lot of benefits besides that given one of decoupling.
First get rid of the following lines from search/models.py:
class Admin:
pass
then, navigate to the folder cms/search which you should have created if you followed the steps verbatim, create a file called admin.py and add the following to it:
from cms.search.models import SearchKeyword
from django.contrib import admin
admin.site.register(SearchKeyword)
Save the file, restart the django webserver and you should see a new group on the admin section for the search app.
HTH
Tags: errata
Posted in Practical Django Projects | 2 Comments »