• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Implementação de
 

Implementação de

on

  • 770 views

 

Statistics

Views

Total Views
770
Views on SlideShare
769
Embed Views
1

Actions

Likes
1
Downloads
4
Comments
0

1 Embed 1

http://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Implementação de Implementação de Presentation Transcript

    • Implementação de Acesso a múltiplos Bancos de dados no Django. Rômulo Jales - rjales@fitec.org.br
    • Agenda ● O que é Django? ● Um rápido Tutorial ● A necessidade ● A solução
    • O que é Django? ● Um framework web de alto nível ● Escrito em Python ● Estimula o desenvolvimento rápido e limpo ● Implementa o conceito DRY “Um framework para perfeccionistas com deadlines”
    • O que é django?
    • Um rápido tutorial ● Crie um projeto: ● django-admin startproject NOME_PRJ ● São criados 4 arquivos: – __init__.py – settings.py – manage.py – urls.py
    • Um rápido tutorial ● settings.py ● Armazena as configurações do serviço ● O banco de dados é configurado aqui! ● urls.py ● Realiza o roteamento das urls para os métodos e recursos ● manager.py ● Gerenciador local do django.
    • Um rápido tutorial ● ./manager startapp NOME_DA_APP ● São criados 4 arquivos – init.py – models.py – view.py – tests.py
    • Um rápido tutorial ● models.py → acesso aos dados ● views.py → Tratamento das requisições da aplicação.
    • Um rápido tutorial ● Código para models.py from django.db import models class Artigo(models.Model): titulo = models.CharField(max_length=100) conteudo = models.TextField() publicacao = models.DateTimeField()
    • Um rápido tutorial ● Crie um arquivo chamado admin.py from django.contrib import admin from models import Artigo admin.site.register(Artigo) ● Edite a urls.py (r'^$', 'django.views.generic.date_based.archive_index', {'queryset': Artigo.objects.all(), 'date_field': 'publicacao'}), (r'^admin/(.*)', admin.site.root),
    • Um rápido tutorial
    • Um rápido tutorial ● Sincronize o banco. ● ./manager syncdb
    • Um rápido tutorial
    • Quem usa o django? ● globo.com ● washingtonpost.com ● E outros 3575 cadastrados no http://www.djangosites.org/!
    • A necessidade ● Acessar vários banco de dados usando a versão em produção 1.1 do cliente.
    • A necessidade ● Solução de acesso atual (na view.py) mssql = _mssql.connect('IP_DO_SERVER','linux','SENHA') query = "SELECT OP FROM CONSULTA_OP WHERE NUMEROSERIE = '"+serial+"'" mssql.query(query)
    • A necessidade ● Solução quebra a arquitetura!!!!!! ● Não é DRY! ● Não é simples! ● Se o IP do banco mudar? ● Se o backend do banco mudar?
    • A solução ● Premissas e restrições: ● Não pode mudar o que já funciona! ● Usar o conceito de DRY ● Funcionar com todos os backends nativos do Django (mysql, postgres, sqlite3) e o **SQL SERVER**
    • A solução - análise connection = backend.DatabaseWrapper({ ‘DATABASE_HOST’: settings.DATABASE_HOST, ‘DATABASE_NAME’: settings.DATABASE_NAME, ‘DATABASE_OPTIONS’: settings.DATABASE_OPTIONS, ‘DATABASE_PASSWORD’: settings.DATABASE_PASSWORD, ‘DATABASE_PORT’: settings.DATABASE_PORT, ‘DATABASE_USER’: settings.DATABASE_USER, ‘TIME_ZONE’: settings.TIME_ZONE, })
    • A solução - análise ● Models ● Tem um atributo _default_manager (Manager) ● Manager ● Tem um método central get_query_set (QuerySet). Método que acessa o backend ● QuerySet ● Tem um atributo query do tipo Query, que é instancia de DataBaseWrapper, que é uma classe abstrata definida pela parametrização contida em settings.py
    • A solução ● Permitir indexação dos parâmetros DATABASE_* ● Modificar a classe QuerySet!!
    • A solução from django.db.models import sql from django.db.models.sql.where import WhereNode from utils import getConnection class MultiBdQuery(sql.Query): def __init__(self, model, banco): self.banco = banco self.connection = getConnection(self.banco) super(MultiBdQuery, self).__init__(model, self.connection, WhereNode) def __setstate__(self, obj_dict): obj_dict['select_fields'] = [ name is not None and obj_dict['model']._meta.get_field(name) or None for name in obj_dict['select_fields'] ] self.__dict__.update(obj_dict) self.connection = getConnection(self.banco)
    • A solução from django.conf import settings from django.db import load_backend def getConnection(banco): engine = settings.SECONDARY_DB[banco]['DATABASE_ENGINE'] if engine == "sql_server.pyodbc": backend = __import__(engine+'.base', {}, {}, ['base']) else: backend = load_backend(engine) return backend.DatabaseWrapper(settings.SECONDARY_DB[banco])
    • A solução from django.db.models import sql from django.db.models.manager import Manager from django.db.models.query import QuerySet from query import MultiBdQuery class MultiBdManager(Manager): use_for_related_fields = True def __init__(self, banco, *args, **kwargs): super(MultiBdManager, self).__init__(*args, **kwargs) self.banco = banco def get_query_set(self): #Obtem um novo query a partir das configuracoes de banco query = MultiBdQuery(self.model, self.banco) return QuerySet(self.model, query)
    • A solução – visão do usuário ● Adicionar no settings.py um dicionário chamado SECONDARY_DB contendo as configurações dos outros bancos ● Novos modelos ● Modificar o Manager padrão, passando o nome do banco de qual a classe está associada.
    • Correção da gambiarra - antes def get_op_from_scf(serial): import _mssql mssql = _mssql.connect('IP_DO_SERVER','linux','SENHA') query = "SELECT OP FROM CONSULTA_OP WHERE NUMEROSERIE = '"+serial+"'" mssql.query(query) ret = mssql.fetch_array() If ret[0][1] == 0: raise Exception("Nao existe nenhuma OP para o numero de serie informado: " + str(serial)) op = ret[0][2][0][0] return op.strip()
    • Correção da gambiarra - depois class OPLEGADO(Model): class Meta: db_table = "CONSULTA_OP" managed = False _default_manager = MultiBdManager("scf") op = CharField(max_length=13,primary_key=True) numeroserie = CharField(max_length=26) def get_op_from_scf(serial): op = OPLEGADO.objects.get(numeroserie=serial) If op: return op else: raise Exception(“"Nao existe nenhuma OP para o numero de serie informado: " + str(serial))
    • Limitações ● Não sincroniza todos os bancos simultaneamente! ● Inicialização mais demorada ● Funciona apenas para versões >= 1.1 do Django.