|
| 1 | +Title: Peewee - Um ORM Python minimalista |
| 2 | +Slug: peewee-um-orm-python-minimalista |
| 3 | +Date: 2017-07-20 23:45:24 |
| 4 | +Category: Python |
| 5 | +Tags: Python, Peewee, ORM, banco de dados |
| 6 | +Author: Michell Stuttgart |
| 7 | +Email: michellstut@gmail.com |
| 8 | +Github: mstuttgart |
| 9 | +Linkedin: michell.stuttgart |
| 10 | +Facebook: michell.stuttgart |
| 11 | +Site: http://codigoavulso.com.br |
| 12 | +Summary: Conheça o Peewee, um prático e minimalista ORM Python |
| 13 | + |
| 14 | +[Peewee](http://peewee.readthedocs.io/en/latest/index.html) é um ORM destinado a criar e gerenciar tabelas de banco de dados relacionais através de objetos Python. Segundo a [wikipedia](https://pt.wikipedia.org/wiki/Mapeamento_objeto-relacional), um ORM é: |
| 15 | +>>> Mapeamento objeto-relacional (ou ORM, do inglês: Object-relational mapping) é uma técnica de desenvolvimento utilizada para reduzir a impedância da programação orientada aos objetos utilizando bancos de dados relacionais. As tabelas do banco de dados são representadas através de classes e os registros de cada tabela são representados como instâncias das classes correspondentes. |
| 16 | +
|
| 17 | +O que o ORM faz é, basicamente, transformar classes Python em tabelas no banco de dados, além de permitir construir *querys* usando diretamente objetos Python ao invés de SQL. |
| 18 | + |
| 19 | +O Peewee é destinado a projetos de pequeno/médio porte, se destacando pela simplicidade quando comparado a outros ORM mais conhecidos, como o SQLAlchemy. Uma analogia utilizada pelo autor da API e que acho muito interessante é que Peewee está para o SQLAlchemy assim como SQLite está para o PostgreSQL. |
| 20 | + |
| 21 | +Em relação aos recursos por ele oferecidos, podemos citar que ele possui suporte nativo a SQLite, PostgreSQL e MySQL, embora seja necessário a instalação de *drivers* para utilizá-lo com PostgreSQL e MySQL e suporta tanto Python 2.6+ quanto Python 3.4+. |
| 22 | + |
| 23 | +Neste tutorial, utilizaremos o SQLite, por sua simplicidade de uso e por não precisar de nenhuma configuração. |
| 24 | + |
| 25 | +### Instalação |
| 26 | + |
| 27 | +O Peewee pode ser facilmente instalado com o gerenciador de pacotes *pip*: |
| 28 | + |
| 29 | +```bash |
| 30 | +pip install peewee |
| 31 | +``` |
| 32 | + |
| 33 | +### Criando o banco de dados |
| 34 | + |
| 35 | +Para criar as tabelas é bem simples. Inicialmente passamos o nome do nosso banco de dados (a extensão `*.db` indica um arquivo do SQLite). |
| 36 | + |
| 37 | +```python |
| 38 | +import peewee |
| 39 | + |
| 40 | +db = peewee.SqliteDatabase('codigo_avulso.db') |
| 41 | + |
| 42 | +``` |
| 43 | + |
| 44 | +Diferente de outros bancos de dados que funcionam através um servidor, o SQLite cria um arquivo de extensão `*.db`, onde todos os nossos dados são armazenados. |
| 45 | + |
| 46 | +**DICA**: caso deseje ver as tabelas existentes no arquivo `codigo_avulso.db`, instale o aplicativo `SQLiteBrowser`. Com ele fica fácil monitorar as tabelas criadas e acompanhar o tutorial. |
| 47 | + |
| 48 | +```bash |
| 49 | + sudo apt-get install sqlitebrowser |
| 50 | +``` |
| 51 | + |
| 52 | +A título de exemplo, vamos criar um banco destinado a armazenar nomes de livros e de seus respectivos autores. Comecemos primeiro com a classe que representa os autores. |
| 53 | + |
| 54 | +```python |
| 55 | +import peewee |
| 56 | + |
| 57 | +db = peewee.SqliteDatabase('codigo_avulso.db') |
| 58 | + |
| 59 | +class Author(peewee.Model): |
| 60 | + """ |
| 61 | + Classe que representa a tabela Author |
| 62 | + """ |
| 63 | + |
| 64 | + # A tabela possui apenas o campo 'name', que |
| 65 | + # receberá o nome do autor |
| 66 | + name = peewee.CharField() |
| 67 | + |
| 68 | + class Meta: |
| 69 | + # Indica em qual banco de dados a tabela |
| 70 | + # 'author' sera criada (obrigatorio). Neste caso, |
| 71 | + # utilizamos o banco 'codigo_avulso.db' criado anteriormente. |
| 72 | + database = db |
| 73 | + |
| 74 | +``` |
| 75 | +Em seguida, criamos a classe que representa os livros. Ela possui uma relação de "muitos para um" com a tabela de autores, ou seja, cada livro possui apenas um autor, mas um autor pode possuir vários livros. |
| 76 | + |
| 77 | +```python |
| 78 | +import peewee |
| 79 | + |
| 80 | +db = peewee.SqliteDatabase('codigo_avulso.db') |
| 81 | + |
| 82 | +class Book(peewee.Model): |
| 83 | + """ |
| 84 | + Classe que representa a tabela Book |
| 85 | + """ |
| 86 | + |
| 87 | + # A tabela possui apenas o campo 'title', que |
| 88 | + # receberá o nome do livro |
| 89 | + title = peewee.CharField() |
| 90 | + |
| 91 | + # Chave estrangeira para a tabela Author |
| 92 | + author = peewee.ForeignKeyField(Author) |
| 93 | + |
| 94 | + class Meta: |
| 95 | + # Indica em qual banco de dados a tabela |
| 96 | + # 'author' sera criada (obrigatorio). Neste caso, |
| 97 | + # utilizamos o banco 'codigo_avulso.db' criado anteriormente. |
| 98 | + database = db |
| 99 | +``` |
| 100 | + |
| 101 | +Agora, vamos reunir tudo em um único arquivo `model.py`. Como exemplo, eu criei um arquivo *main.py* para utilizarmos as classes que acabamos de criar. |
| 102 | + |
| 103 | +```python |
| 104 | + |
| 105 | +import peewee |
| 106 | +from model import Author, Book |
| 107 | + |
| 108 | + |
| 109 | +if __name__ == '__main__': |
| 110 | + try: |
| 111 | + Author.create_table() |
| 112 | + except peewee.OperationalError: |
| 113 | + print 'Tabela Author ja existe!' |
| 114 | + |
| 115 | + try: |
| 116 | + Book.create_table() |
| 117 | + except peewee.OperationalError: |
| 118 | + print 'Tabela Book ja existe!' |
| 119 | + |
| 120 | +``` |
| 121 | + |
| 122 | +Após executarmos o código, será criado um arquivo de nome `codigo_avulso.db` no mesmo diretório do nosso arquivo `main.py`, contendo as tabelas `Author` e `Book`. A estrutura do diretório ficou assim: |
| 123 | + |
| 124 | +```bash |
| 125 | +. |
| 126 | +├── codigo_avulso.db |
| 127 | +├── main.py |
| 128 | +├── model.py |
| 129 | +``` |
| 130 | + |
| 131 | +### Inserindo dados no banco |
| 132 | + |
| 133 | +Agora, vamos popular nosso banco com alguns autores e seus respectivos livros. Isso pode ser feito de dois modos. Através do método `create`, quando desejamos inserir um registro apenas; ou pelo método `insert_many`, quando desejamos inserir vários registros de uma vez em uma mesma tabela. |
| 134 | + |
| 135 | +```python |
| 136 | + |
| 137 | +# Inserimos um autor de nome "H. G. Wells" na tabela 'Author' |
| 138 | +author_1 = Author.create(name='H. G. Wells') |
| 139 | + |
| 140 | +book_1 = { |
| 141 | + 'title': 'A Máquina do Tempo', |
| 142 | + 'author': author_1, |
| 143 | +} |
| 144 | + |
| 145 | +book_2 = { |
| 146 | + 'title': 'Guerra dos Mundos', |
| 147 | + 'author': author_1, |
| 148 | +} |
| 149 | + |
| 150 | +# Inserimos um autor de nome "Julio Verne" na tabela 'Author' |
| 151 | +author_2 = Author.create(name='Julio Verne') |
| 152 | + |
| 153 | +book_3 = { |
| 154 | + 'title': 'Volta ao Mundo em 80 Dias', |
| 155 | + 'author': author_2, |
| 156 | +} |
| 157 | + |
| 158 | +book_4 = { |
| 159 | + 'title': 'Vinte Mil Leguas Submarinas', |
| 160 | + 'author_id': author_1, |
| 161 | +} |
| 162 | + |
| 163 | +books = [book_1, book_2, book_3, book_4] |
| 164 | + |
| 165 | +# Inserimos os quatro livros na tabela 'Book' |
| 166 | +Book.insert_many(books).execute() |
| 167 | + |
| 168 | +``` |
| 169 | + |
| 170 | +### Consultando dados no banco |
| 171 | + |
| 172 | +O Peewee possui comandos destinados a realizar consultas no banco. De maneira semelhante ao conhecido `SELECT`. Podemos fazer essa consulta de duas maneiras. Se desejamos o primeiro registro que corresponda a nossa pesquisa, podemos utilizar o método `get()`. |
| 173 | + |
| 174 | +```python |
| 175 | +book = Book.get(Book.title == "Volta ao Mundo em 80 Dias").get() |
| 176 | +book.title |
| 177 | +``` |
| 178 | +Porém, se desejamos mais de um registro, utilizamos o método `select`. Por exemplo, para consultar todos os livros escritos pelo autor "H. G. Wells". |
| 179 | + |
| 180 | +```python |
| 181 | +books = Book.select().join(Author).where(Author.name=='H. G. Wells') |
| 182 | + |
| 183 | +# Exibe a quantidade de registros que corresponde a nossa pesquisa |
| 184 | +print books.count() |
| 185 | + |
| 186 | +for book in books: |
| 187 | + book.title |
| 188 | + |
| 189 | +# Resultado: |
| 190 | +# * A Máquina do Tempo |
| 191 | +# * Guerra dos Mundos |
| 192 | +# * Vinte Mil Leguas Submarinas |
| 193 | + |
| 194 | +``` |
| 195 | + |
| 196 | +Também podemos utilizar outras comandos do SQL como `limit` e `group` (para mais detalhes, ver a documentação [aqui](http://peewee.readthedocs.io/en/latest/index.html)). |
| 197 | + |
| 198 | +### Alterando dados no banco |
| 199 | + |
| 200 | +Alterar dados também é bem simples. No exemplo anterior, se observarmos o resultado da consulta dos livros do autor "H. G. Wells", iremos nos deparar com o livro de título "Vinte Mil Léguas Submarinas". Se você, caro leitor, gosta de contos de ficção-científica, sabe que esta obra foi escrito por "Julio Verne", coincidentemente um dos autores que também estão cadastrados em nosso banco. Sendo assim, vamos corrigir o autor do respectivo livro. |
| 201 | + |
| 202 | +Primeiro vamos buscar o registro do autor e do livro: |
| 203 | + |
| 204 | +```python |
| 205 | +new_author = Author.get(Author.name == 'Julio Verne') |
| 206 | +book = Book.get(Book.title=="Vinte Mil Leguas Submarinas") |
| 207 | +``` |
| 208 | +Agora vamos alterar o autor e gravar essa alteração no banco. |
| 209 | + |
| 210 | +```python |
| 211 | +# Alteramos o autor do livro |
| 212 | +book.author = new_author |
| 213 | + |
| 214 | +# Salvamos a alteração no banco |
| 215 | +book.save() |
| 216 | +``` |
| 217 | + |
| 218 | +### Deletando dados do banco |
| 219 | + |
| 220 | +Assim como as operações anteriores, também podemos deletar registros do banco de maneira bem prática. Como exemplo, vamos deletar o livro "Guerra dos Mundos" do nosso banco de dados. |
| 221 | + |
| 222 | +```python |
| 223 | +# Buscamos o livro que desejamos excluir do banco |
| 224 | +book = Book.get(Book.title=="Guerra dos Mundos") |
| 225 | + |
| 226 | +# Excluimos o livro do banco |
| 227 | +book.delete_instance() |
| 228 | +``` |
| 229 | +Simples não? |
| 230 | + |
| 231 | +### Conclusão |
| 232 | + |
| 233 | +É isso pessoal. Este tutorial foi uma introdução bem enxuta sobre o Peewee. Ainda existem muitos tópicos que não abordei aqui, como a criação de *primary_key*, de campos *many2many* entre outros recursos, pois foge do escopo deste tutorial. Se você gostou do ORM, aconselho a dar uma olhada também na sua documentação, para conseguir extrair todo o potencial da ferramenta. A utilização de um ORM evita que o desenvolvedor perca tempo escrevendo *query* SQL e foque totalmente no desenolvimento de código. |
| 234 | + |
| 235 | +O Peewee também possui suporte ao flamework *flask*, então dependendo do tamanho do projeto, pode ser uma alternativa interessante no lugar de ORM mais complexos como o SQLAlchemy. |
| 236 | + |
| 237 | +É isso pessoal. Obrigado pela leitura e até o próximo tutorial! |
| 238 | + |
| 239 | +### Referências |
| 240 | + |
| 241 | +* [Documentação do Peewee (em inglês)](http://peewee.readthedocs.io/en/latest/index.html) |
| 242 | +* [An Intro to peewee – Another Python ORM](https://www.blog.pythonlibrary.org/2014/07/17/an-intro-to-peewee-another-python-orm/) |
| 243 | +* [Introduction to peewee](http://jonathansoma.com/tutorials/webapps/intro-to-peewee/) |
| 244 | +* [Introdução à Linguagem SQL](https://www.novatec.com.br/livros/introducao-sql/) |
| 245 | + |
0 commit comments