Pythone especialmente o Django, são essenciais para construir aplicações mais eficientes, com menos código, e ligadas a uma base de dados altamente escalonável. Estou aqui para vos falar sobre a redução do atrito diário que vem com a construção e apoio a aplicações modernas utilizando SQL e Python para abstrair a complexidade e tornar os nossos trabalhos e vidas um pouco mais fáceis.
Sem entrar nas ervas daninhas, podemos assumir:
- SQL está optimizado para bases de dados SQL
- Python não está optimizado para bases de dados SQL
Este exercício suporta directamente o ebook Understanding Databases e a minha nova série educativa Linode LIVE! usando Python e ferramentas Pythonic para executar comandos em SQL em bruto sem a necessidade de escrever SQL de facto. Estou a usar a modelação de dados de Django, mas a sintaxe é muito semelhante ao pacote SQLAlchemy em Python.
Vamos começar!
Aquiestá um exemplo de um modelo de dados Django:
class BlogArticle(models.Model):
user = models.ForeignKey(User, default=1, on_delete=models.SET_DEFAULT)
title = models.CharField(max_length=120)
slug = models.SlugField(blank=True, null=True)
content = models.TextField(blank=True, null=True)
publish_timestamp = models.DateTimeField(
auto_now_add=False,
auto_now=False,
blank=True,
null=True,
)
Vamos assumir que este modelo vive numa aplicação Django chamada Articles
(As aplicações Django são essencialmente componentes que constituem a totalidade de um projecto Django).
Agora temos dois nomes para trabalhar:
Articles
(nome do aplicativo)BlogArticle
(nome do modelo)
Em combinação, estes traduzem-se para o nome da Tabela SQL:
articles_blog_article
Django faz esta magia por nós.
Se estivéssemos a utilizar a concha MySQL, veríamos:
mysql> SHOW TABLES;
+------------------------------+
| Tables_in_cfe_django_blog_db |
+------------------------------+
| articles_blog_article |
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+------------------------------+
11 rows in set (0.01 sec)
Agora vejamos as colunas do nosso modelo Django:
mysql> DESCRIBE articles_blog_article;
+------------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+--------------+------+-----+---------+----------------+
| id | bigint | NO | PRI | NULL | auto_increment |
| title | varchar(120) | NO | | NULL | |
| slug | varchar(50) | YES | MUL | NULL | |
| content | longtext | YES | | NULL | |
| publish_timestamp | datetime(6) | YES | | NULL | |
| user_id | int | NO | MUL | NULL | |
+------------------------+--------------+------+-----+---------+----------------+
12 rows in set (0.00 sec)
Para além de escrever uma configuração básica, Django fez todo o trabalho SQL para nós nesta base de dados MySQL. Neste momento, Django não fez nada de muito impressionante. De facto, a maior parte deste exercício não foi concebido para destacar Django ou Python como um substituto de SQL, mas para lembrar o facto de que as abstracções funcionam.
A Ascensão de Python e o Custo do Atrito
Vamos falar sobre o caminho de menor resistência e porque acredito que Python é uma das melhores formas de alavancar o SQL.
É muito fácil de escrever, ler, correr E enviar Python. Alterar "Python" para quase qualquer outro paradigma de programação e é quase impossível fazer a mesma afirmação. O JavaScripté também um concorrente, mas é também consistentemente confundido para Java. Compreendo que estas são generalizações, e nem sempre são verdadeiras, mas são questões comuns que surgem ao desenvolver a sua aplicação.
Creio que estas generalizações tendem a ser verdadeiras devido à sintaxe inglesa de fazer as coisas Python.
Vamos comparar uma declaração SQL com uma declaração Python e Django:
- SQL:
SELECT * from articles_blog_article;
- Python e Django:
items = BlogArticle.objects.all()
Ambas as declarações produzem exactamente os mesmos dados. A declaração Python , contudo, devolve uma lista de Python objectos (items
) que quase qualquer desenvolvedor Python com uma vasta experiência pode utilizar. Os resultados em bruto do SQL teriam de ser convertidos antes de serem utilizados numa aplicação Python .
Descrições de campo
Se olharmos mais de perto para esta descrição de campo SQL:
+------------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+--------------+------+-----+---------+----------------+
| title | varchar(120) | NO | | NULL | |
+------------------------+--------------+------+-----+---------+----------------+
Versus esta descrição de campo Django:
title = models.CharField(max_length=120)
- Qual deles tem mais fricção?
- Qual deles é mais fácil de compreender o que se passa?
O que fornece apenas informação suficiente?
Se não fosse um programador e serrasse varchar(120)
o que pensaria disso? Tenho quase a certeza de que conseguiria pelo menos adivinhar o que max_length=120 means
. O mais fixe é que significam exactamente a mesma coisa: limitar este campo a 120 caracteres ou menos.
Acrescentar dados à base de dados
Com Django:
BlogArticle.objects.create(
title="Hello World",
content="Coming Soon",
slug="hello-world",
publish_timestamp=None,
)
Com SQL:
INSERT INTO `articles_blog_article` (`user_id`, `title`, `slug`, `content`, `publish_timestamp`)
VALUES (1, 'Hello World', 'hello-world', 'Coming Soon', NULL);
Quando se trata de simplicidade e clareza, penso que o vencedor acima é definitivamente Django e Python. title = "Hello World"
é mais fácil do que descobrir o que está a acontecer com o valor equivalente da coluna (campo) em SQL. Não se enganem, a forma como isto é escrito em SQL é muito eficaz quando se sabe o que se está a fazer.
Adição de Várias Linhas
com Django:
items = [
BlogArticle(title='Hello Again 0', slug='hello-again-0', content="Coming Soon"),
BlogArticle(title='Hello Again 1', slug='hello-again-1', content="Coming Soon"),
BlogArticle(title='Hello Again 2', slug='hello-again-2', content="Coming Soon"),
BlogArticle(title='Hello Again 3', slug='hello-again-3', content="Coming Soon"),
BlogArticle(title='Hello Again 4', slug='hello-again-4', content="Coming Soon"),
]
BlogArticle.objects.bulk_create(items)
Com SQL:
INSERT INTO `articles_blog_article` (`user_id`, `title`, `slug`, `content`, `publish_timestamp`)
VALUES (1, 'Hello Again 0', 'hello-again-0', 'Coming Soon', NULL),
(1, 'Hello Again 1', 'hello-again-1', 'Coming Soon', NULL),
(1, 'Hello Again 2', 'hello-again-2', 'Coming Soon', NULL),
(1, 'Hello Again 3', 'hello-again-3', 'Coming Soon', NULL),
(1, 'Hello Again 4', 'hello-again-4', 'Coming Soon', NULL);
Mais uma vez, o código Python é mais legível enquanto que o código SQL dá mais informações sobre os dados reais. E, mais uma vez, Python está a escrever este código SQL para nós utilizando o código Django acima. Bastante limpo, huh?
A razão pela qual mergulhei nesta comparação lado a lado não é para escolher, que é a melhor maneira de aproveitar as bases de dados SQL, mas para destacar a capacidade de Pythonde ajudar a reduzir a sobrecarga de aprendizagem para escrever SQL em bruto directamente.
Há vários pacotes Python que essencialmente escrevem o SQL em bruto para si, aqui estão alguns deles:
- Django
- Pandas
- SQLAlchemy
- Polares
- Dask
- Vaex
- PythonMódulo CSV incorporado no CSV
- Tartaruga ORM
- Pónei ORM
- SQLObject
Django Faz o Levantamento Pesado
Os pacotes de mapeamento objeto-relacional (geralmente referidos como ORMs) são o molho secreto de como Python pode aproveitar as bases de dados SQL. Penso num ORM como um intermediário que ajuda a mover os dados na sintaxe nativa de qualquer linguagem de programação.
No início deste exercício, começámos a ver como isto se traduzia para Django, mas vamos agora expandir isto.
Assumindo que temos dados na nossa base de dados, podemos escrever um comando como este:
my_post = BlogArticle.objects.first()
Esta declaração irá consultar a nossa base de dados, extrair os dados, carregá-los para uma instância de Python Class
e, em seguida, atribuí-la à variável my_post
.
A partir daqui, podemos agora fazer algo como isto:
# using a django-managed python shell
# via python manage.py shell
>>> print(my_post.title)
Hello World
Neste caso, utilizámos a notação de pontos para aceder ao title
campo que foi declarado no BlogPost
Modelo Django da secção anterior. Este campo corresponde a uma coluna na nossa tabela da base de dados SQL articles_blog_article
.
Graças à ORM, podemos fazer isto:
>>> my_post.title = "some other title"
Dentro deste exemplo de sessão de shell Python , o my_post.title
irá agora sempre ser "some other title"
. A base de dados SQL subjacente, no entanto, ainda reconhece estes mesmos dados que Hello World
. A base de dados manterá os dados originais até que Python finalmente se comprometa (aka .save()
) estes dados mudam para a base de dados. Se Python nunca submeter estes dados, eles nunca serão actualizados na base de dados, o que faz parte da magia do ORM. Nós podemos utilização e alteração os dados sem afectar os dados efectivamente armazenados. Quando queremos alterar o que está realmente a acontecer na base de dados, corremos:
>>> my_post.title = "some other title again"
>>> my_post.save()
Depois de correr .save()
a nossa base de dados, para esta linha em particular, actualizará o título da coluna para corresponder exactamente ao que está escrito como uma string Python acima. Não se esqueça que a .save()
é especificamente para fazer compromissos com a base de dados em modelos Django. .save()
não significa realmente nada para um Python Class
sem herdar primeiro um formulário Django Model Class.
Construção com Django, MySQL, e Linode
Este é um dos muitos exemplos de como Django faz o trabalho pesado para si. Se estiver interessado numa abordagem moderna de implantação de aplicações Django em Linode juntamente com uma base de dados MySQL gerida, GitHub Actions for CI/CD, Terraform, e Ansible, consulte o seguinte conteúdo agora disponível em Linode:
- Veja a nossa Série de Tutoriais em Vídeo de Bases de Dados sobre Linode LIVE!
- Descarregar as bases de dados de compreensão: Livro Ebook Edição Alargada
Para o ajudar a começar, o Código para Empresários GitHub tem um repositório de código que acompanha cada passo da série. Boa sorte, e não deixe de me informar como as coisas estão a correr através do Twitter @JustinMitchel.
Comentários