SlideShare uma empresa Scribd logo
1 de 28
Baixar para ler offline
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.

Mais conteúdo relacionado

Mais procurados

Acesso a banco de dados com JDBC
Acesso a banco de dados com JDBCAcesso a banco de dados com JDBC
Acesso a banco de dados com JDBC
Eduardo Mendes
 
Aula 09 - Instruções preparadas e otimização de consultas do Mysql - Program...
Aula 09  - Instruções preparadas e otimização de consultas do Mysql - Program...Aula 09  - Instruções preparadas e otimização de consultas do Mysql - Program...
Aula 09 - Instruções preparadas e otimização de consultas do Mysql - Program...
Dalton Martins
 
LabMM4 (T16 - 12/13) - PHP + MySQL
LabMM4 (T16 - 12/13) - PHP + MySQLLabMM4 (T16 - 12/13) - PHP + MySQL
LabMM4 (T16 - 12/13) - PHP + MySQL
Carlos Santos
 
Desenvolvimento em .Net - A Framework e o Visual Studio
Desenvolvimento em .Net - A Framework e o Visual StudioDesenvolvimento em .Net - A Framework e o Visual Studio
Desenvolvimento em .Net - A Framework e o Visual Studio
Vitor Silva
 

Mais procurados (20)

Acesso a banco de dados com JDBC
Acesso a banco de dados com JDBCAcesso a banco de dados com JDBC
Acesso a banco de dados com JDBC
 
JDBC
JDBCJDBC
JDBC
 
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010
 
Dinamizando Sites Estáticos
Dinamizando Sites EstáticosDinamizando Sites Estáticos
Dinamizando Sites Estáticos
 
Mini Curso PHP Twig - PHP Conference 2017
Mini Curso PHP Twig - PHP Conference 2017 Mini Curso PHP Twig - PHP Conference 2017
Mini Curso PHP Twig - PHP Conference 2017
 
Minicurso mongo db
Minicurso mongo dbMinicurso mongo db
Minicurso mongo db
 
Aula 09 - Instruções preparadas e otimização de consultas do Mysql - Program...
Aula 09  - Instruções preparadas e otimização de consultas do Mysql - Program...Aula 09  - Instruções preparadas e otimização de consultas do Mysql - Program...
Aula 09 - Instruções preparadas e otimização de consultas do Mysql - Program...
 
LabMM4 (T16 - 12/13) - PHP + MySQL
LabMM4 (T16 - 12/13) - PHP + MySQLLabMM4 (T16 - 12/13) - PHP + MySQL
LabMM4 (T16 - 12/13) - PHP + MySQL
 
Palestra PHPSP+Locaweb 2014 - PDO
Palestra PHPSP+Locaweb 2014 - PDOPalestra PHPSP+Locaweb 2014 - PDO
Palestra PHPSP+Locaweb 2014 - PDO
 
Crawling - Coleta de dados na Web com PHP
Crawling - Coleta de dados na Web com PHP Crawling - Coleta de dados na Web com PHP
Crawling - Coleta de dados na Web com PHP
 
BigData - ElasticSearch + PHP
BigData - ElasticSearch + PHPBigData - ElasticSearch + PHP
BigData - ElasticSearch + PHP
 
Persistência Java: Hibernate e JPA
Persistência Java: Hibernate e JPAPersistência Java: Hibernate e JPA
Persistência Java: Hibernate e JPA
 
Mongo Db - PHP Day Workshop
Mongo Db - PHP Day WorkshopMongo Db - PHP Day Workshop
Mongo Db - PHP Day Workshop
 
Mongodb workshop cinlug
Mongodb workshop cinlugMongodb workshop cinlug
Mongodb workshop cinlug
 
Sql proficiente
Sql proficienteSql proficiente
Sql proficiente
 
PHP e Mysql - DELETE
PHP e Mysql - DELETEPHP e Mysql - DELETE
PHP e Mysql - DELETE
 
Mongo DB
Mongo DBMongo DB
Mongo DB
 
Desenvolvimento em .Net - A Framework e o Visual Studio
Desenvolvimento em .Net - A Framework e o Visual StudioDesenvolvimento em .Net - A Framework e o Visual Studio
Desenvolvimento em .Net - A Framework e o Visual Studio
 
Fundamentos de JDBC
Fundamentos de JDBCFundamentos de JDBC
Fundamentos de JDBC
 
Jdbc, JAVA DATABASE CONNECTIVITY
Jdbc, JAVA DATABASE CONNECTIVITYJdbc, JAVA DATABASE CONNECTIVITY
Jdbc, JAVA DATABASE CONNECTIVITY
 

Destaque (7)

Curriculo maikel méndez
Curriculo maikel méndezCurriculo maikel méndez
Curriculo maikel méndez
 
Carnavla
CarnavlaCarnavla
Carnavla
 
IntegraçãO Da Be No Processo De A V
IntegraçãO Da Be No Processo De A VIntegraçãO Da Be No Processo De A V
IntegraçãO Da Be No Processo De A V
 
Uva
UvaUva
Uva
 
NoçõEs Basicas De CulináRia 08
NoçõEs Basicas De CulináRia 08NoçõEs Basicas De CulináRia 08
NoçõEs Basicas De CulináRia 08
 
Estela
EstelaEstela
Estela
 
53
5353
53
 

Semelhante a Implementação de

Uma implementação de suporte a
Uma implementação de suporte a Uma implementação de suporte a
Uma implementação de suporte a
Rômulo Jales
 
Oficina postgresql avançado_consegi2010
Oficina postgresql avançado_consegi2010Oficina postgresql avançado_consegi2010
Oficina postgresql avançado_consegi2010
Fabrízio Mello
 

Semelhante a Implementação de (20)

Uma implementação de suporte a
Uma implementação de suporte a Uma implementação de suporte a
Uma implementação de suporte a
 
Aplicacoes Rapidas Para Web Com Django
Aplicacoes Rapidas Para Web Com DjangoAplicacoes Rapidas Para Web Com Django
Aplicacoes Rapidas Para Web Com Django
 
Python 06
Python 06Python 06
Python 06
 
Treinamento Básico de Django
Treinamento Básico de DjangoTreinamento Básico de Django
Treinamento Básico de Django
 
Dsi 015 - poo e php - conexão com bancos de dados usando pdo
Dsi   015 - poo e php - conexão com bancos de dados usando pdoDsi   015 - poo e php - conexão com bancos de dados usando pdo
Dsi 015 - poo e php - conexão com bancos de dados usando pdo
 
Desenvolvimento de aplicações para o Google App Engine
Desenvolvimento de aplicações para o Google App EngineDesenvolvimento de aplicações para o Google App Engine
Desenvolvimento de aplicações para o Google App Engine
 
Desenvolvimento de Aplicações para o Google App Engine (CPBR5)
Desenvolvimento de Aplicações para o Google App Engine (CPBR5)Desenvolvimento de Aplicações para o Google App Engine (CPBR5)
Desenvolvimento de Aplicações para o Google App Engine (CPBR5)
 
Oficina PostgreSQL Básico Latinoware 2012
Oficina PostgreSQL Básico Latinoware 2012Oficina PostgreSQL Básico Latinoware 2012
Oficina PostgreSQL Básico Latinoware 2012
 
Introdução ao framework CodeIgniter
Introdução ao framework CodeIgniterIntrodução ao framework CodeIgniter
Introdução ao framework CodeIgniter
 
Boas práticas de django
Boas práticas de djangoBoas práticas de django
Boas práticas de django
 
Desenvolvimento ágil com Kohana framework
Desenvolvimento ágil com Kohana frameworkDesenvolvimento ágil com Kohana framework
Desenvolvimento ágil com Kohana framework
 
Django: Desenvolvendo uma aplicação web em minutos
Django: Desenvolvendo uma aplicação web em minutosDjango: Desenvolvendo uma aplicação web em minutos
Django: Desenvolvendo uma aplicação web em minutos
 
Backbone.js nas trincheiras
Backbone.js nas trincheirasBackbone.js nas trincheiras
Backbone.js nas trincheiras
 
Oficina postgresql avançado_consegi2010
Oficina postgresql avançado_consegi2010Oficina postgresql avançado_consegi2010
Oficina postgresql avançado_consegi2010
 
Python 07
Python 07Python 07
Python 07
 
Django Módulo Básico Parte II
Django Módulo Básico Parte IIDjango Módulo Básico Parte II
Django Módulo Básico Parte II
 
Mini curso de django
Mini curso de djangoMini curso de django
Mini curso de django
 
Modulos SNEP
Modulos SNEPModulos SNEP
Modulos SNEP
 
Conectando seu banco de dados usando jdbc
Conectando seu banco de dados usando jdbcConectando seu banco de dados usando jdbc
Conectando seu banco de dados usando jdbc
 
LambdaDay: Backbone.js
LambdaDay: Backbone.jsLambdaDay: Backbone.js
LambdaDay: Backbone.js
 

Mais de Rômulo Jales

IMPLEMENTAÇÃO DO UNIVERSEAL HOST CONTROLLER INTERFACE (UHCI) PARA O MEMTE...
IMPLEMENTAÇÃO DO UNIVERSEAL  HOST CONTROLLER INTERFACE    (UHCI) PARA O MEMTE...IMPLEMENTAÇÃO DO UNIVERSEAL  HOST CONTROLLER INTERFACE    (UHCI) PARA O MEMTE...
IMPLEMENTAÇÃO DO UNIVERSEAL HOST CONTROLLER INTERFACE (UHCI) PARA O MEMTE...
Rômulo Jales
 
Implementação UHCI para Memtest86+
Implementação UHCI para Memtest86+Implementação UHCI para Memtest86+
Implementação UHCI para Memtest86+
Rômulo Jales
 

Mais de Rômulo Jales (9)

Conhecimentos básicos para construir um portal que atenda 10milhões de pesoas
Conhecimentos básicos para construir um portal que atenda 10milhões de pesoasConhecimentos básicos para construir um portal que atenda 10milhões de pesoas
Conhecimentos básicos para construir um portal que atenda 10milhões de pesoas
 
Construindo sua primeira ontologia
Construindo sua primeira ontologiaConstruindo sua primeira ontologia
Construindo sua primeira ontologia
 
Introdução a Model Based User Interface Design
Introdução a Model Based User Interface DesignIntrodução a Model Based User Interface Design
Introdução a Model Based User Interface Design
 
Bridge GoF Patern
Bridge GoF PaternBridge GoF Patern
Bridge GoF Patern
 
Usando Django para servir 12 milhões de usuários
Usando Django para servir 12 milhões de usuáriosUsando Django para servir 12 milhões de usuários
Usando Django para servir 12 milhões de usuários
 
Seminario pic
Seminario picSeminario pic
Seminario pic
 
DKMS ­ Dynamic Kernel Module Support
DKMS ­ Dynamic Kernel Module SupportDKMS ­ Dynamic Kernel Module Support
DKMS ­ Dynamic Kernel Module Support
 
IMPLEMENTAÇÃO DO UNIVERSEAL HOST CONTROLLER INTERFACE (UHCI) PARA O MEMTE...
IMPLEMENTAÇÃO DO UNIVERSEAL  HOST CONTROLLER INTERFACE    (UHCI) PARA O MEMTE...IMPLEMENTAÇÃO DO UNIVERSEAL  HOST CONTROLLER INTERFACE    (UHCI) PARA O MEMTE...
IMPLEMENTAÇÃO DO UNIVERSEAL HOST CONTROLLER INTERFACE (UHCI) PARA O MEMTE...
 
Implementação UHCI para Memtest86+
Implementação UHCI para Memtest86+Implementação UHCI para Memtest86+
Implementação UHCI para Memtest86+
 

Implementação de

  • 1. Implementação de Acesso a múltiplos Bancos de dados no Django. Rômulo Jales - rjales@fitec.org.br
  • 2. Agenda ● O que é Django? ● Um rápido Tutorial ● A necessidade ● A solução
  • 3. 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”
  • 4. O que é django?
  • 5. 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
  • 6. 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.
  • 7. Um rápido tutorial ● ./manager startapp NOME_DA_APP ● São criados 4 arquivos – init.py – models.py – view.py – tests.py
  • 8. Um rápido tutorial ● models.py → acesso aos dados ● views.py → Tratamento das requisições da aplicação.
  • 9. 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()
  • 10. 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),
  • 12. Um rápido tutorial ● Sincronize o banco. ● ./manager syncdb
  • 14. Quem usa o django? ● globo.com ● washingtonpost.com ● E outros 3575 cadastrados no http://www.djangosites.org/!
  • 15. A necessidade ● Acessar vários banco de dados usando a versão em produção 1.1 do cliente.
  • 16. 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)
  • 17. 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?
  • 18. 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**
  • 19. 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, })
  • 20. 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
  • 21. A solução ● Permitir indexação dos parâmetros DATABASE_* ● Modificar a classe QuerySet!!
  • 22. 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)
  • 23. 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])
  • 24. 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)
  • 25. 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.
  • 26. 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()
  • 27. 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))
  • 28. Limitações ● Não sincroniza todos os bancos simultaneamente! ● Inicialização mais demorada ● Funciona apenas para versões >= 1.1 do Django.