Django Utilidades :: Marinho Brandaohttp://marinhobrandao.com/pt-brTue, 06 Jan 2009 09:45:35 -0000Versão 0.6 do Yadsel com suporte a Djangohttp://marinhobrandao.com/blog/p/versao-06-do-yadsel-com-suporte-a-django/<div class="document"> <p>Depois de um longo período apenas mantendo a estabilidade da versão atual, tirei ontem o dia para concluir os ajustes necessários para a versão 0.6 do <strong>Yadsel</strong>, com foco quase que exclusivo em projetos construídos com Django.</p> <p>Ocorre que antes disso, o Yadsel trabalhava somente com versões de forma linear, ou seja: <strong>uma classe, uma versão</strong>.</p> <p>Isso permaneceu até a versão 0.4, quando implementei o recurso de Extensible Versions (versões extensíveis) e Partial Versions (versões parciais). Essa versão inaugurou a idéia de poder ter várias classes em uma só versão. Melhorou na organização dos arquivos de versões e possibilitou trabalhar várias aplicações compartilhando uma mesma versão.</p> <p>Mas ainda assim, outro recurso era necessário para o uso cotidiano no Django. No Django, as aplicações são independentes umas das outras, e ainda assim, podem haver eventuais dependências. Isso cria a necessidade de suporte a múltiplas versões em um mesmo projeto, ou seja: <strong>cada aplicação, uma versão</strong>. Para isso foi necessário implementar o <strong>Version Space</strong>.</p> <p><strong>Version Space</strong></p> <p>O Version Space é um recurso novo do Yadsel que torna possível que cada &quot;espaço&quot; no controle de versões possua sua própria versão, histórico e log. No caso do Django, o version space traduz-se pelo nome da aplicação, em outros aplicações, o desenvolvedor pode implementar como bem quiser.</p> <p>Em outras palavras: eu posso manter uma aplicação de newsletter em diversos projetos com evolução de versões independentes do restante, incluindo toda a parafernália de DDL e DML que o Yadsel suporta: Tabelas, Domínios, Triggers, Procedures, Views, etc.</p> <p><strong>Yadsel no Admin</strong></p> <p>No embalo do Version Space veio o suporte ao Admin. É simples, ao instalar a aplicação <strong>'yadsel.drivers.django_app'</strong> em seu INSTALLED_APPS, seu Admin passará a exibir duas seções para visualizar logs e históricos da evolução do banco.</p> <p><strong>Yadsel pelo manage.py</strong></p> <p>O Yadsel implementa um novo comando ao manage.py: <strong>yadseltool</strong>. A lógica de funcionamento é a mesma da yadseltool independente, porém seguindo a sintaxe de comandos baseados aplicações do manage.py:</p> <pre><code>$ python manage.py help yadseltool Usage: manage.py yadseltool [options] [appname ...] Executes Yadsel database version control for the given app name(s). Options: --settings=SETTINGS The Python path to a settings module, e.g. "myproject.settings.main". If this isn't provided, the DJANGO_SETTINGS_MODULE environment variable will be used. --pythonpath=PYTHONPATH A directory to add to the Python path, e.g. "/home/djangoprojects/myproject". --traceback Print traceback on exception --action=ACTION Action of evolution; up=upgrade, down=downgrade --from=FROM --to=TO --mode=MODE Mode of output; hidden=messages are hidden, steps=step by step, interactive=confirms actions, output=only prints to output --test=TEST Set test mode --history=HISTORY Write history of versions --silent=SILENT Keeps exception messages --log=LOG Write a log of changes --version show program's version number and exit -h, --help show this help message and exit</code></pre><p><strong>Exemplo de chamada do yadseltool</strong></p> <pre><code>$ python manage.py yadseltool minha_aplicacao</code></pre><p><strong>Mas como afinal utilizar o Yadsel em meu projeto Django?</strong></p> <p>Bom, primeiro é necessário baixar a versão 0.6 do Yadsel em sua máquina</p> <blockquote> <a class="reference" href="http://yadsel.googlecode.com/files/yadsel-0.6-with-django-support.tar.gz">http://yadsel.googlecode.com/files/yadsel-0.6-with-django-support.tar.gz</a></blockquote> <p>Feito o download, instale o Yadsel numa versão 2.4 ou superior do Python</p> <pre><code>$ python setup.py install</code></pre><p>Em seu projeto, acrescente a seguinte aplicação à setting <strong>INSTALLED_APPS</strong> do arquivo <strong>settings.py</strong></p> <blockquote> 'yadsel.drivers.django_app'</blockquote> <p>Rode o <strong>syndcb</strong></p> <pre><code>$ python manage.py syncdb</code></pre><p>Serão criadas as duas tabelas necessárias para o histórico e log do Yadsel. Entenda que <strong>'histórico'</strong> trata-se do controle das versões, é ele que sabe se sua aplicação está na versão X ou Y. O <strong>'log'</strong> trata-se de cada comando SQL que é gerado e executado, assim como suas respectivas eventuais mensagens de erro.</p> <p>Crie a seguinte estrutura de pastas em uma de suas aplicações:</p> <pre><code>minha_aplicacao/ minha_aplicacao/yadsel_versions/ minha_aplicacao/yadsel_versions/__init__.py minha_aplicacao/yadsel_versions/versao1.py minha_aplicacao/yadsel_versions/versao2.py minha_aplicacao/yadsel_versions/versaoN.py</code></pre><p>o arquivo __init__.py deve conter ou importar as classes de versões, que podem ser estruturadas como bem quiser, seja em módulos ou em pacotes.</p> <p>O conteúdo provável do arquivo __init__.py será este:</p> <pre><code>from versao1 import *</code></pre><p>E o do arquivo versao1.py (ou qualquer outro que contenha classes de versões) será provavelmente este:</p> <pre><code>from yadsel.core import * class Version1(Version): version_number = 1 def up(self): pass def down(self): pass</code></pre><p>ou como este exemplo:</p> <pre><code>from yadsel.core import * class MinhaVersao1(Version): version_number = 1 def up(self): CreateTable('minha_tabela_nova', id = Integer(primary=True) name = Varchar(50, required=True), ).append_to(self) AlterTable('states', Add('percent', Decimal(15, 5, default=0)), ).append_to(self) ExecuteSQL(""" Create or Alter Procedure sp_teste... """).append_to(self) def down(self): ExecuteSQL(""" Drop Procedure sp_teste """).append_to(self) AlterTable('states', DropColumn('percent'), ).append_to(self) DropTable('minha_tabela_nova').append_to(self)</code></pre><p>A minha sugestão é que se use o Yadsel no Django somente para manter a evolução, não para criar tabelas em si. Isso porque o Django o já cria as tabelas muito bem. O que ele não faz é o resto :D</p> </div> Grupos de discussão do Yadselhttp://marinhobrandao.com/blog/p/grupos-de-discussao-do-yadsel_127/<div class="document"> <p>Fiz alguns ajustes no Yadsel <a class="footnote-reference" href="#id4" id="id1" name="id1">[1]</a> e incrementei a versão para 0.3:</p> <ul class="simple"> <li>Ajustado o suporte a DELETE, que estava falhando;</li> <li>Ajustado o parsing das clausulas OR e NOT, que estavam funcionando como AND, também foi feita uma garantia de precedência de operadores / grupos de condições, através de parênteses;</li> </ul> <p>Também criei os seguintes grupos de discussão:</p> <ul class="simple"> <li>yadsel-users <a class="footnote-reference" href="#id5" id="id2" name="id2">[2]</a></li> <li>yadsel-developers <a class="footnote-reference" href="#id6" id="id3" name="id3">[3]</a></li> </ul> <p><strong>Links relacionados</strong></p> <table class="docutils footnote" frame="void" id="id4" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> <tr><td class="label"><a class="fn-backref" href="#id1" name="id4">[1]</a></td><td><a class="reference" href="http://code.google.com/p/yadsel">http://code.google.com/p/yadsel</a></td></tr> </tbody> </table> <table class="docutils footnote" frame="void" id="id5" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> <tr><td class="label"><a class="fn-backref" href="#id2" name="id5">[2]</a></td><td><a class="reference" href="http://groups.google.com/group/yadsel-users">http://groups.google.com/group/yadsel-users</a></td></tr> </tbody> </table> <table class="docutils footnote" frame="void" id="id6" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> <tr><td class="label"><a class="fn-backref" href="#id3" name="id6">[3]</a></td><td><a class="reference" href="http://groups.google.com/group/yadsel-developers">http://groups.google.com/group/yadsel-developers</a></td></tr> </tbody> </table> </div> Yadsel - Statushttp://marinhobrandao.com/blog/p/yadsel-status_89/Bom, muita correria nos últimos dias. Pouco tempo para publicar qualquer coisa, mas o Yadsel, o Guia de Django e o Adorador.es estão vivos como nunca. Neste momento a prioridade é o <a href="http://code.google.com/p/yadsel/">Yadsel</a>, por motivos de urgência em alguns aplicativos reais, em produção. O Guia segue caminhando para a conclusão e já com alguns contatos sobre publicação em curso. O <a href="http://adorador.es">Adorador.es</a> também está de pé, esperando tempo hábil para atualização da versão 0.3. O Yadsel ainda está registrado como versão <strong>0.1-unstable</strong>. Ainda que o nome impressione imaturidade, o software está caminhando para uma relativa maturidade, essencialmente sobre o driver de <strong>Firebird</strong>. Os drivers para MySQL e SQLite também foram melhorados e foi introduzido o driver para MSSQL (SQL Server). O foco é deixar toda a framework e core API maduras e partir daí para atacar os drivers em andamento, sempre preocupado com cases reais, nunca com teorias. A arquitetura está muito boa, minha impressão é de que superamos as espectativas, pois todas as manutenções necessárias até agora foram extremamente simples e claras, e o software está com uma performance também melhor que o esperado. Destaques das últimas tarefas efetuadas: <strong>yadseltool</strong> <ul> <li>para sistema operacional Windows, agora ofecere um executável standalone para poder ser embutido em aplicações sem necessidade da máquina virtual.</li> <li>melhorado toda a forma de interpretar os argumentos, agora em forma de atribuição.</li> <li>oferece agora 4 modos: hidden (persiste sem exibir mensagens), output (apenas escreve o script na tela, sem persistência), steps (persiste exibindo uma mensagem de progresso a cada etapa), interactive (confirma cada etapa antes de persistir - não implementado ainda)</li> <li>agora suporta modo de teste - sem persistência</li> <li>agora suporta controle do histórico embutido</li> </ul> <p align="center"><a href="http://marinho.webdoisonline.com/blog/wp-content/uploads/2007/08/yadseltool1.png" title="yadseltool"><img src="http://marinho.webdoisonline.com/blog/wp-content/uploads/2007/08/yadseltool1.thumbnail.png" alt="yadseltool"></a></p> <p align="left">&nbsp;</p> <p align="left"><strong>HistoryControl</strong></p> <p align="left">Recurso para embutir controle das atualizações. Antes este controle era feito externamente, pelo utilizador.</p> <p align="left">&nbsp;</p> <p align="left"><strong>PartialVersions</strong></p> <p align="left">Foi implementado o recurso de partial versions - conceito semelhante ao PartialClass, do Delphi - através do qual se pode quebrar uma só versão em várias classes e arquivos, juntando tudo numa Version só. Muito bom para situações de script completo ou grandes modificações.</p> <p align="left">&nbsp;</p> <p align="left"><strong>ZipFile</strong></p> <p align="left">O suporte a arquivos ZIP como repositório das versões foi liberado e será até mesmo recomendado, dado que é mais seguro e limpo.</p> <p align="left">&nbsp;</p> <p align="left"><strong>DocTests</strong></p> <p align="left">Alguns doctests foram criados para automatizar os testes de funcionalidades básicas:</p> <p align="left">&nbsp;</p> <ul> <li>PartialVersions</li> <li>Persistencia</li> <li>ZipFiles</li> </ul> <strong>GTKYadsel</strong> Uma ferramenta de manutenção de projetos foi criada para auxiliar o desenvolvedor e, num futuro ideal, tornar desnecessário o conhecimento de programação a quem for construir modelos de banco. Esta ferramenta trabalho no sentido de construir projetos e dar a ele uma ou mais conexões, ao qual também se pode adicionar versões e editar em um editor com highlight de sintaxe. Evidentemente, funciona melhor no Linux, mas a screenshot abaixo, tirada sob o Windows, demosntra que ele pode ser eficaz em qualquer ambiente. Ainda não está bom o suficiente para recomendar o uso, mas eu já o uso normalmente. <p align="center"><a href="http://marinho.webdoisonline.com/blog/wp-content/uploads/2007/08/gtk_yadsel1.png" title="GTKYadsel"><img src="http://marinho.webdoisonline.com/blog/wp-content/uploads/2007/08/gtk_yadsel1.thumbnail.png" alt="GTKYadsel"></a></p> <strong>FullVersionBuilder</strong> Por fim, este também é um recurso cada vez mais estável. A versão completa de um dos casos reais onde o Yadsel é utilizado foi toda gerada a partir deste, com pequenos ajustes posteriores relacionados a valores DateTime. <strong>Conclusão</strong> Como podem ver, o Yadsel caminhou a passos largos. O tempo disponível não é grande, é realmente curto, mas está indo muito bem. Espero soltar a versão 0.2-stable rapidamente, ainda esta semana provavelmente. Boa sorte para todos nós!DBMigrations será YADSELhttp://marinhobrandao.com/blog/p/dbmigrations-sera-yadsel_76/O project <a href="http://code.google.com/p/dbmigrations/">DBMigrations</a> terá o nome definitivo de <a href="http://code.google.com/p/yadsel/"><strong>"yadsel"</strong></a>, sigla de "Yet Another Database Schema Evolution Library". O motivo para eu tomar esta decisão se deve ao fato de que o nome antigo era provisório e também porque descobri que já existia <a href="http://www.aswmc.com/dbmigration/">um projeto com o mesmo nome</a>.DBMigrationshttp://marinhobrandao.com/blog/p/dbmigrations/Publiquei a seguinte mensagem nas listas <strong>python-brasil</strong> e <strong>django-brasil</strong>: <pre>Saudações! senhores, como eu havia comentado há uns dias atrás, estive trabalhando em um "migrations" para um projeto em Django e outro em Delphi. criei então o DBMigrations (ainda não tive idéia para um nome melhor), que é basicamente uma ferramenta que pode ser usada como executável ou como modulo de um software em Python, para controle de evolução de bancos de dados, sob a LGPL, e independente de ORMs e SGBDs e que possa ser útil para projetos feitos em outras linguagens. a notação é mais ou menos semelhante ao Active Record Migrations, do Rails. ele fornece um grupo de classes (uma espécie de API), que é interpretada por um driver (por enquanto somente o MySQL está implementado, os proximos serão o Firebird e o SQLite), e este driver aplica as especificidades de cada SGBD. da forma como ficou estruturado, ele permite que sejam criados drivers para ORMs, como Django, SQLAlchemy ou SQLite, etc. a primeira versão (0.1) ainda não foi devidamente testada, pois irei utiliza-la oficialmente amanhã, numa virada de versão. E ainda não suporta stored procs, triggers, views, sequences ou indices (este ultimo não concluído). o repositório do projeto é: <a href="http://code.google.com/p/dbmigrations/" target="_blank">http://code.google.com/p/dbmigrations/</a> quem gostar da idéia e tiver interesse em participar, principalmente criando drivers, será bem-vindo :) espero que seja útil.</pre>