Django - Composição de queries brutas (raw queries)

Django Rest Framework (DRF) é uma poderosa ferramenta para criar Web APIs. Ele requer o uso de Python e do framework Django. Mesmo o Django já trazendo seu próprio ORM (Object Relational Mapping), o que facilita enormemente a construção de consultas SQL, em algum momento da aplicação pode ser necessário lançar mão de consultas brutas.

O DRF oferece duas maneiras de executar consultas cruas: a primeira utiliza o método raw() da classe Manager e a segunda faz acesso direto ao banco de dados. Independente da maneira que se adote, não se pode perder de vista a preocupação com a segurança no que diz respeito à injeção de SQL.

Supondo que já temos uma aplicação Django criada e rodando e que temos um model denominado Client, este código é um exemplo do que seria a primeira maneira:

client_id = 101
clients = Client.objects.raw(
  "SELECT * FROM client WHERE id = %s",
  [client_id]
)
for client in clients:
  print(client.name)
Caso optemos pelo acesso direto ao banco de dados, podemos fazer assim:
from django.db import connection

client_id = 101
with connection.cursor() as cursor:
  cursor.execute(
	"SELECT * FROM client WHERE id = %s",
  	[client_id]
  )
  client.cursor.fetchone()
  print(client[1])
Essas soluções se aplicam quando os parâmetros são valores mesmo no comando SQL. Consideremos o caso em que seja necessário especificar dinamicamente nomes de tabelas, campos ou nomes de schema. Neste cenário é útil o pacote psycopg2, levando em conta que a API acessa um banco de dados PostgreSQL.
Para usar este pacote, o primeiro passo consiste em instalá-lo, por exemplo, utilizando pip install psycopg2.
Deste pacote, será utilizado o módulo sql, para a composição de string SQL de forma segura, e duas classes do módulo: SQL, a qual representa um comando SQL, e Identifier, a qual representa um identificar PostgreSQL ou uma sequência de identificadores separados por ponto.
Aqui está um trecho de código que exemplifica o uso de psycopg2 para compor um comando SQL:
from django.db import connection
from psycopg2 import sql

client_id = 101
with connection.cursor() as cursor:
  cursor.execute(
    sql.SQL("SELECT * FROM {table_name} WHERE id = %s").format(
      table_name = sql.Identifier("schema", "client")
    ),
    [client_id]
  )
  client.cursor.fetchone()
  print(client[1])
A classe Identifier se aplica a um marcador {} na string SQL, neste exemplo {table_name}. Pode-se passar um ou mais parâmetros em Identifier. Caso sejam mais de um, eles aparecerão separados por ponto na query composta. Aqui estamos passando o nome do schema e o nome da tabela. Desse modo, após a composição a query ficará:
SELECT * FROM "schema"."client" WHERE id = %s
Como dissemos anteriormente, de modo análogo, é possível especificar nomes de campos.

Mais detalhes podem ser obtidos na documentação do Django.

Lazarus - Recursos do Editor de Código

Neste post vamos apresentar alguns dos inúmeros recursos que o Editor de Código oferece aos desenvolvedores. O Editor pode ser configurado via menu em Tools | Options | Editor. Estas opções também podem ser acessadas através do menu de contexto.

O detalhamento das opções e configuração do Editor exige um post específico, portanto não iremos nos ater a isso no momento. Queremos falar de recursos que a ferramenta oferece para facilitar o trabalho do programador.

Syncron

Esta é uma opção onde podemos rapidamente modificar o nome de um identificador em um trecho de código  selecionado.

Quando você seleciona um trecho do código (ou o código inteiro), no lado esquerdo do Editor aparece um ícone com uma caneta. Clique nesse ícone ou tecle CTRL + J. A área selecionada muda de cor e o cursor é movido para uma instância do identificador, destacando cada uma de suas ocorrências naquela área. Modifique o identificador e cada ocorrência dele será alterada automaticamente.
Volte a clicar no ícone ou tecle ESC para sair do modo syncron.

O Code Completion é um dos recursos que pode poupar muito tempo de digitação. Dependendo da posição do cursor no Editor, várias funções podem ser chamadas.

Complementação de classe

Se você escreveu uma classe incluindo propriedades e métodos, este recurso irá adicionar o corpo do método, variáveis e métodos de acesso às propriedades, etc. Suponha que você tenha criado a seguinte classe:

TPessoa = class(TObject)
    constructor Create;
    destructor Destroy; override;
    property nome: string;
end;

Posicione o cursor no interior da classe e pressione CTRL + SHIFT + C. O código seguinte será gerado, e o cursor será movido para que o corpo do primeiro método seja digitado.

type

  { TPessoa }

  TPessoa = class(TObject)
  private
    Fnome: string;
    procedure Setnome(AValue: string);
  published
    constructor Create;
    destructor Destroy; override;
    property nome: string read Fnome write Setnome;
  end;

implementation

{ TPessoa }

procedure TPessoa.Setnome(AValue: string);
begin
  if Fnome=AValue then exit;
  Fnome:=AValue;
end;

constructor TPessoa.Create;
begin

end;

destructor TPessoa.Destroy;
begin
  inherited Destroy;
end;

Complementação de declaração de variável

Se o cursor é posicionado em um identificador e for pressionado CTRL + SHIFT + C, é adicionado ao código uma declaração de variável local. Por exemplo, imagine o seguinte código fonte:

procedure TForm1.FormClick(Sender: TObject);
begin
  i := 5;
end;

Posicione o cursor na variável i (antes ou depois) e pressione CTRL + SHIFT + C. O código será modificado e ficará assim:

procedure TForm1.FormClick(Sender: TObject);
var
  i: Integer;
begin
  i := 5;
end;

O tipo da variável é deduzida a partir da expressão.

Message Composer

O Message Composer é uma ferramenta que auxilia na criação de caixas de diálogos,  tais ShowMessage, MessageDlg e InputBox. Para isso é necessário instalar o pacote messagecomposerpkg. Vá em Package | Install/Uninstall packages. Na lista Do not install localize e selecione messagecomposerpkg. Clique em Install selection e depois em Save and rebuild IDE. Em seguida clique no botão Continue para confirmar. Após o IDE ser reiniciado uma nova opção será adicionada ao menu Source. Você também pode usar o atalho CTRL + M. Esta opção irá abrir a seguinte janela:
Após escolher o tipo de mensagem, os parâmetros demais opções, confirme em OK e o diálogo selecionado será adicionado no seu código na posição do cursor.

Dicas para funções e procedimentos

Se você não lembra dos parâmetros, ordem, tipos de dados de uma função ou procedimento, digite a mesma e dentro dos parênteses tecle CTRL + SHIFT + ESPAÇO. Irá aparecer uma janela de dica com os argumentos:
À medida que um argumentos é digitado, o próximo fica em destaque na janela. Um botão à direita permite colar os parâmetros no código fonte.

Templates

Templates são modelos que podem ser inseridos no código. Por exemplo, suponha que você deseja inserir um comando case no seu código. Digite casee no ponto onde deseja inserir e tecle CRTL + J. Será inserido o seguinte código, e o cursor será posicionado no local onde deve ser inserida a variável do comando.
Existem vários modelos prontos, mas você pode criar os seus próprios templates usando a opção Tools | Code Templates. Na janela que será aberta você usará o botão Add para adicionar novo modelo.
Clique aqui para ver um rápido tutorial de como criar novos modelos. Por enquanto é isso que temos. Aproveite os recursos e explore mais possibilidades com o Lazarus

Lazarus - Usando Dicionários de Dados

Nos dois posts anteriores:
Lazarus - O Lazarus Data Desktop e
Lazarus - Dicionário de Dados
estudamos a ferramenta Lazarus Data Desktop e como criar dicionários de dados. Neste artigo iremos mostrar como usar os dicionários nas aplicações desenvolvidas usando Lazarus.
Como já falamos, um dicionário de dados descreve entre outras coisas os atributos dos campos das tabelas de um esquema de banco de dados. E essa descrição, também chamada de metadados, pode ser usada nas aplicações para evitar que tenhamos que repetir essas definições em cada DataSet. Assim, vamos supor que já exista um dicionário de dados criado para um tabela chamada PRODUTO. E vamos mostrar como usar o dicionário de dados em tempo de execução e como aplicá-lo em tempo de desenvolvimento.
O primeiro passo é o mesmo necessário para acessar qualquer tabela sem usar o recurso do dicionário de dados. Supondo que estejamos usando ZeosLib, coloque todos os componentes que são precisos, no Data Module: ZConnection, ZQuery e um DataSource. Faça todas as configurações exigidas. Agora crie os campos persistentes TFields para a ZQuery - este é um procedimento obrigatório para o funcionamento do dicionário de dados. Dê um duplo clique na ZQuery e você verá uma pequena janela como na figura abaixo:
Clique no botão com o sinal de + ou pressione CTRL + INS para inserir os campos. Uma nova janela mostrando todos os campos da tabela correspondente será mostrada, como a figura a seguir:
Selecione todos os campos e pressione o botão Create.

Usando dicionário de dados em run-time

Uma maneira de usar o dicionário de dados em tempo de execução é inserir o código, por exemplo, no evento OnCreate do Data Module. A classe TFPDataDictionary está localizada na unit fpdatadict. Portanto, é necessário declarar esta unit na cláusula uses no módulo onde será instanciada TFPDataDictionary. Assim, nosso código poderá ficar assim:

procedure TdmData.DataModuleCreate(Sender: TObject);
var
  Dict : TFPDataDictionary;
begin
  Dict := TFPDataDictionary.Create;
  // carrega o arquivo do dicionário de dados
  Dict.LoadFromFile('produto.fpd');
  // aplica o dicionário ao DataSet
  Dict.ApplyToDataset(queProduto);
  // libera a memória usada pelo dicionário de dados
  Dict.Free;
end;

Num form você pode inserir um TDBGrid, onde serão mais facilmente visualizados os efeitos que desejamos.  Associe essa grade ao DataSource que está ligado ao DataSet onde foi aplicado o dicionário.
Agora execute o programa e você poderá constatar que todas as definições feitas no dicionário de dados serão assumidas pelos TFields que foram criados.

Usando dicionário de dados em tempo de projeto

Neste caso, o primeiro passo é registrar no projeto o dicionário desejado. Isso é feito usando a opção de menu Project > Data Dictionary > Set ... Quando selecionar este item de menu um diálogo será aberto:
Marque a caixa Use Data dictionary for this project. E selecione o dicionário de dados desejado. Confirme pressionando OK.
Agora localize o DataSet e clique com o botão direito sobre ele. Selecione o item Data dictionary e depois em Apply.
Isso irá aplicar o dicionário ao DataSet, da mesma forma que fizemos usando código. Agora podemos executar o programa e aproveitar o recurso.
Post escrito tendo como referência o livro Lazarus - the Complete Guide, publicado pela Blaise Pascal Magazine.

Lazarus - Dicionários de Dados

Dicionários de dados são repositórios com metadados sobre bancos de dados, que descrevem a estrutura básica de um esquema de banco de dados. Num dicionário de dados as seguintes informações são armazenadas: as tabelas e os campos correspondentes, e os índices existentes nas tabelas. Além disso, os dicionários de dados contém atributos que definem como o conteúdo dos campos devem ser visualizados: número de casas decimais, o rótulo, a dica (hint) mostrada, tamanho do campo, entre outros.
Um dicionário de dados pode ser usado por uma aplicação Lazarus para definir as propriedades dos objetos TField; pode ser usado para criar comandos SQL, por exemplo, para criar o banco de dados descrito; e, a partir da comparação entre dois dicionários, as diferenças entre eles podem ser usadas para criar um script de atualização.
Os dicionários de dados podem ser mantidos usando o Lazarus Data Desktop, que começamos a descrever no post Lazarus - o Lazarus Data Desktop. Usando esta ferramenta podemos criar um dicionário novinho em folha ou importá-lo a partir de um banco de dados existente.

Criando um Dicionário de Dados

Para criar um novo dicionário clique no botão correspondente na barra de ferramentas conforme mostra a figura, ou tecle CTRL + N.
Isso irá criar uma nova aba. Clique com o botão direito no interior da aba e em seguida na opção New Table, ou tecle CTRL + T, para criar uma nova tabela. Digite o nome da tabela na caixa de diálogo e confirme.
Agora clique com o botão direito sobre o nome da tabela recém-criada e escolha a opção New Field. Digite o nome do campo e confirme. Um novo campo será criado e um formulário para definir as propriedades do campo será aberto no lado direito da interface, como podemos ver na figura abaixo.
Algumas propriedades que podem ser definidas, entre outras:
DisplayName - rótulo do campo que poderá ser visualizado em uma TDBGrid, por exemplo;
DisplayWidth - tamanho com que o campo será exibido;
FieldType - tipo de dado do campo;

Após criar todas as tabelas e campos, tecle CTRL + S para salvar.

Gerando comandos SQL a partir do Dicionário

Para gerar os comandos SQL pressione o botão correspondente conforme mostra a figura abaixo ou tecle CTRL + G.
Essa ação irá abrir um novo formulário. Escolha a tabela para a qual deseja gerar os comandos SQL. Na lista Key fields selecione o(s) campo(s) que será chave primária. Na lista Select/Update/Insert fields selecione o(s) campo(s) que serão usados nos comandos SELECT, UPDATE e INSERT. Pressione o botão Generate SQL. Clique em cada uma das abas para ver os comandos gerados. Na figura seguinte mostramos o comando CREATE TABLE que foi gerado.

Importando o Dicionário de Dados

Se já tivermos um banco de dados criado, podemos criar o dicionário a partir dele - processo que é chamado engenharia reversa.
Inicialmente crie uma conexão para o banco de dados existente conforme mostramos em Lazarus - o Lazarus Data Desktop. Em seguida selecione no menu Dictionary > Import > From connection. As conexões criadas na ferramenta estarão disponíveis nessa opção. Escolha aquela para a qual você precisa criar o dicionário.
Uma caixa de diálogo será aberta mostrando as tabelas do esquema. Selecione as tabelas desejadas, deixe marcada a caixa Update existing tables para atualizar tabelas que já existem e confirme.
Se houver um dicionário ativo na ferramenta, você será questionado se deseja atualizar ou criar um novo. Clique CTRL + S para salvar o dicionário. Os dicionários de dados são salvos com a extensão .fpd. Você pode visualizar o arquivo de dicionário de dados usando qualquer programa que abre arquivos texto.
Fica para o próximo post a utilização de dicionários de dados em aplicações Lazarus.
Post escrito tendo como referência o livro Lazarus - the Complete Guide, publicado pela Blaise Pascal Magazine.

Lazarus - O Lazarus Data Desktop

Se em suas aplicações você utiliza diversos bancos de dados, é provável que também precise de uma ferramenta específica para cada SGBD, com a finalidade de criar tabelas, criar comandos DML e DDL, entre outros. A fim de centralizar todas as tarefas do desenvolvedor no Ambiente de Desenvolvimento, o Lazarus oferece o Lazarus Data Desktop. Também chamado Database Desktop, esta ferramenta dispõe de vários recursos, dentre os quais destacamos:
  • Acesso a todos os bancos de dados suportados pelo Lazarus;
  • Criação de um dicionário de dados onde as propriedades de TFields podem ser armazenadas;
  • Criação de comandos DDL e DML a partir do dicionário de dados;
  • Consulta à tabelas;
  • Exportação de dados de tabelas para diversos formatos: XML, JSON, CSV, entre outros.
Para usar esta ferramenta. primeiramente é necessário compilá-la. Ela está localizada em tools/lazdatadesktop, no diretório home do Lazarus. Abra então o projeto lazdatadesktop e compile-o.
Para integrar a ferramenta ao IDE, abra e instale o pacote lazDataDict, localizado no diretório components/datadict. Após isso o IDE será estendido em três novas opções:
  1. Um novo item de menu será registrado no menu Project - com o nome Data Dictionary. Esta opção irá permitir que escolhamos um dicionário de dados para o projeto;
  2. No menu Tools será acrescentado o item de menu Database Desktop, que executa o Lazarus Data Desktop;
  3. Finalmente no Form Designer, um novo item é registrado no menu local que pode ser usado para aplicar o dicionário de dados a um TDataset - o item de menu Data Dictionary.
Vejamos então como utilizar o Lazarus Data Desktop.

Conectando-se a bancos de dados

Para fazer uma conexão use a opção de menu Connections > New connection, como mostra a figura abaixo:
Esta ação abrirá uma caixa de diálogo onde você irá escolher o banco de dados:
Selecione o banco de dados e você será levado a um novo diálogo para informar os dados da conexão:
Após informar os dados e confirmar será solicitado um nome para a conexão. Confirme também, após informar o nome e será adicionada uma nova aba ao ambiente com as informações da conexão. No lado direito da tela existe a aba Run Query,  que possibilita executar uma consulta e exportar o resultado da consulta, entre outros recursos.

Exportando dados de uma tabela

Para exportar os dados resultantes de uma consulta, use o botão Export this data que será habilitado após a execução bem sucedida de uma Query. Em seguida escolha o tipo de arquivo, por exemplo CSV, e confirme. Então será mostrado um diálogo onde se pode escolher os campos da tabela a serem exportados, o caminho e o nome do arquivo destino e opções de formatação, conforme pode ser visto na figura a seguir.
Depois de confirmar o arquivo exportado será criado.

Gerando código Free Pascal

Outro recurso importante do Lazarus Data Desktop é a criação de código em Free Pascal. Pode-se gerar código quando estamos visualizando o resultado de uma Query ou quando estamos examinando a definição de uma tabla no dicionário de dados.
Os códigos que podem ser gerados são:
  • Uma constante string a partir do comando SQL quando se está visualizando o resultado de uma consulta;
  • O código para criar uma tabela DBF a partir dos dados que estão sendo mostrados;
  • Uma classe Object Pascal e suas propriedades baseados em um Dataset e seus campos;
  • Uma declaração de classe tiOPF para usar com Object Persistence Framework.
Por exemplo, na aba Run Query, após executar uma consulta, clique no botão Create pascal code for this data. Escolha em seguida a opção Simple object/collection for the data. Será aberto o seguinte diálogo:
Nessa tela você define o caminho e nome do arquivo onde deseja salvar o código e os campos da tabela que serão propriedades da classe. Para cada campo da tabela é possível definir propriedades, bem como definir algumas propriedades da própria classe na aba Options. Confirme e uma tela com o código gerado será aberta, conforme mostra a figura seguinte:
Apesar de ter um botão Save, isso não será mais necessário, pois o código já está salvo no arquivo informado na tela anterior.
No próximo post veremos os procedimentos para criar dicionários de dados no Lazarus Data Desktop e como utilizá-los em nossas aplicações de banco de dados.
Post escrito tendo como referência o livro Lazarus - the Complete Guide, publicado pela Blaise Pascal Magazine.

Lazarus - Livro sobre Lazarus em Português

"Desenvolvendo Aplicativos com Lazarus" (agbook, 2011, 344 páginas), produzido pelo paraense Jean Patrick, reúne um conjunto de informações valiosas sobre o IDE Lazarus, que chegam em boa hora para suprir uma necessidade urgente daqueles que, ou pretendem adotar uma nova ferramenta de desenvolvimento ou gostariam de melhorar seu conhecimento sobre o IDE.
O livro está organizado em 14 capítulos e 5 apêndices. Sendo que os nove primeiros capítulos passam por vários tópicos, alguns bem superficialmente tal como as paletas de componentes, e dá mais destaque à configuração no IDE no Capítulo 6.
Para os que preferem ação, ela começa mesmo no Capítulo 10. Nesse capítulo são desenvolvidos três projetos, o que dá uma boa noção do poder de fogo do Lazarus. Os projetos usam componentes básicos e há farta utilização de eventos e código. Desta forma o leitor terá um bom suporte para o que vem pela frente, que é o desenvolvimento usando banco de dados.
Uma introdução a banco de dados é feita no Capítulo 11. No Capítulo 12 são usados os componentes nativos do Lazarus para conexão a bancos de dados - a paleta SQLdb. Aqui é criada uma aplicação para controle de cheques usando o banco de dados sqlite.
Um cadastro de produtos usando banco de dados Firebird é criado no Capítulo 13. Neste caso o livro apresenta o conjunto de componentes ZeosLib, ZeosLib é uma biblioteca de terceiros e considerada melhor que SQLdb para aplicações de maior porte.
A criação de relatórios é abordada no Capítulo 14, onde se destaca o conjunto LazReport, nativo do Lazarus. Documentação sobre LazReport é muito raro. Esse é capítulo que vai ajudar muito aos desenvolvedores.
Nos apêndices destacamos os recursos do IDE para tratamento de arquivos texto e algumas dicas para programar aplicações multiplataforma. Inclusive é criada uma pequena aplicação para demonstrar o uso dos componentes oferecidos pelo Lazarus para acessar arquivos texto.
É uma obra que precisa do incentivo da comunidade para crescer ainda mais. Costumo dizer que só com a divulgação de conteúdo de valor é que será possível a disseminação do uso deste poderoso IDE.
Os interessados em adquirir um exemplar acessem o site da agbook.

Curso de Introdução ao Free Pascal/Lazarus - Gratuito

Desenvolver aplicações usando um IDE como o Lazarus, pressupõe conhecimento da linguagem de programação subjacente. Pois a criação de um programa sempre irá precisar que se escreva algum código, principalmente para os eventos. No caso do Lazarus estamos falando do Free Pascal. Este é um curso introdutório ao Free Pascal oferecido na modalidade à distância e está organizado em oito módulos:

1. Princípios básicos, tipos, variáveis, constantes e comando de atribuição
2. Comandos condicionais (if)
3. Comandos de repetição (while, repeat e for)
4. Tipos definidos pelo usuário (subrange, set, enumerados, arrays, registros)
5. Ponteiros
6. Procedimentos e funções
7. Manipulação de strings
8. Classes e objetos

O curso será ministrado no ambiente virtual de aprendizagem Moodle. É uma ferramenta voltada para ensino à distância com todos os recursos de um ambiente dessa natureza: chat, fórum, exercícios, questionários, etc.
Caso você tenha interesse em fazer o curso, faça sua pré-inscrição aqui. Assim que completarmos a turma enviaremos um e-mail a você informando a data de início do curso e seu login e senha de acesso ao ambiente de aprendizagem.
Pré-inscrições encerradas.

Atualizado em 03/07/2011.

Django - Composição de queries brutas (raw queries)

Django Rest Framework (DRF) é uma poderosa ferramenta para criar Web APIs. Ele requer o uso de Python e do framework Django. Mesmo o Django...