Páginas

quarta-feira, 13 de abril de 2011

Django + SQL Server no LINUX



13/04/2010

Recente mente eu tive uns probleminhas ao tentar usar em um projeto o Django com o Microsoft SQL Server 2008, sendo que o Django está em uma maquina Linux.

O primeiro problema foi como acessar, pois o Django não tem suporte nativo ao SQL Server.
Encontrei alguns módulos de terceiros que fazia o serviço, só que se o Django estivesse no windows.
Ex: django-mssql só funciona no Windows, usa uma outro modulo que não tem similar para Linux.

Minha saida foi usar o pymssql, que se demonstrou ser muito eficiente.
Depois de ter aberto o SQL Server para TCP na porta 1433, consegui lo
gar com o pymssql facilmente, mas ainda tive uns obstáculos a superar.

A minha ferramenta era para migração de dados, tirar o SQL Server e
colocar no MySQL.
primeiro problema foi a codificação. O Django usa o UTF8 e o SQL Server usa o "CP1252" (demorou para saber). Conversor do array:

def rowdecode(row):
row2=[]
for item in row:
if type(item)==str:
txt = unicode(item, 'cp1252')
row2.append( txt )
else:
row2.append( item )
return row2

O outro problema é que os nomes das colunas no SQL Server estavam bem "espirados" tinha colunas com mais de 30 caracteres no nome. A solução estava a query de solicitação:

SELECT [nome_muito_muito_longo_como_esse] AS nome_curto form FROM [base].[dbo].[bdo_tabela]

e o terceiro problema é que campos nvarchar do SQL Server pode ser maior que o varchar do MySQL

sendo assim usei o CAST para corrigir o tamanho .

Por último, na minha importação tinha mais de 5 milhões de entradas (era uma tabela com logs importantes da aplicação) o Django começou a consumir cada vez mais memória, até a maquina ficar lenta e eu tive de interromper a operação.
Foi pesquisar o que estava ocorrendo quando descobri que o Django manter um histório em memória das query enviadas ao banco.
A solução foi ficar esvaziando esse histórico, dai o espaço em memória ficou baixo e estável durante a toda a importação.

def salva(row):
from django.db import connection
dado = LogHistorico(.......................)
dado.save()
connection.queries.pop()

Quase nada de para superar, como a ajuda pela internet foi escassa resolvi portar no meu blog.
Espero que ajude a mais alguem.