Uma rápida pesquisa de colegas no meu projeto atual mostrou que, com as palavras "ORM e trabalhando com o banco de dados", na grande maioria dos casos, as palavras "Alquimia" e "Django ORM" soam. O conhecimento dessas duas palavras, em geral, é suficiente para escrever um código limpo, limpo e funcional. Mas a expansão dos horizontes da engenharia não prejudicou ninguém até agora; portanto, hoje adicionaremos à nossa imagem do mundo algumas peças interessantes (talvez até hoje desconhecidas) para trabalhar com o banco de dados.

Yoyo
Hoje, qualquer ORM vem com um sistema interno de migração de banco de dados. Uma abordagem simples e interessante, quando o ORM monitora a estrutura das tabelas, em geral, serve a todos. Mas esta solução tem um caso em que é inconveniente usá-la:
Existem pessoas que solicitam figuat em um banco de dados, ignorando o ORM. Isso usa algo como asyncpg e uma pequena mancha auto-escrita para simplificar a compilação de solicitações.
Por que esses caras estão desistindo das comodidades do ORM? Sim, porque qualquer wrapper para o banco de dados consome uma certa quantidade de recursos do sistema, e esses caras precisam escrever código de alto desempenho. Eles jogaram fora o ORM e, de alguma forma, precisam migrar a base.
- Os migrantes internos podem ter suas próprias visões específicas sobre registros de vinculação e indexação. Às vezes, não é possível derrotar essas visualizações ORM na estrutura das tabelas;
Nos dois casos, é conveniente aplicar migrações manuais - não confiamos nos modelos ORM, mas com as mãos digitamos as instruções SQL necessárias e as alimentamos em um migrador simples que aplica seqüencialmente alterações estruturais no banco de dados.
A saída é uma estrutura de tabela limpa, compreensível e totalmente gerenciável, compilada com sabedoria.
Para essa abordagem manual, existe um migrador de esquema de banco de dados yoyo .
pip install yoyo-migrations
Em seguida, todo o trabalho de gerenciamento de migração é feito usando o executável yoyo
yoyo new ./migrations -m "Add column to foo"
O comando cria um arquivo no qual você pode inserir uma ou mais instruções para migrar o esquema
from yoyo import step steps = [ step("CREATE TABLE foo (id INT, bar VARCHAR(20), PRIMARY KEY (id))", "DROP TABLE foo"), ]
Após essa migração, você pode rolar para a base
yoyo apply --database postgresql://scott:tiger@localhost/db ./migrations
Tudo é simples, como logs. E, ao mesmo tempo, você tem controle absolutamente completo sobre a aparência do banco de dados.
Existem duas desvantagens nessa abordagem.
- O conjunto de campos nas tabelas e seus parâmetros terão que ser seguidos por alças. Cada alteração leva à necessidade de escrever ALTER TABLE , a capacidade de migrar tudo em um clique é perdida.
- A fusão dessas migrações também sempre terá que ser feita com as mãos e a cabeça. Obviamente, isso é um trabalho supérfluo. Mas, na prática, conflitos e fusões complexas de migração são raros.
Peewee

Um ORM pequeno e não o mais popular (embora tenha sido escrito aqui mais de uma vez), que, no entanto, tem seu próprio público.
O Peewee foi projetado para ser o invólucro mais estúpido e simples do banco de dados, com o mecanismo de execução de consultas mais compreensível e código de fácil leitura.
Users.select().where( Users.user_id == user_id ).get()
Apesar de sua simplicidade, minimalismo e uma pequena quantidade de código, a peewee tem tudo o que é necessário para um trabalho sadio.
- Desempenho adequado (embora não seja a velocidade de execução da consulta mais rápida)
- Todas as vantagens necessárias - vários conjuntos de campos, relacionamentos entre entidades, conjuntos de conexões, conjuntos de plugins e extensões.
- Há ainda mais ou menos asynchronism sane adicionado pelo módulo peewee_async de terceiros.
Orm do pônei
Pony é um invólucro lendário. A camada de banco de dados criada usando esse ORM pode acelerar a parte traseira de outras soluções às vezes. Não há mágica em sua velocidade, há uma política muito competente de cache de solicitações para os bancos de dados, montes de otimizações e truques com o código. No total, isso leva ao fato de o pônei fritar em velocidade de cavalo.
O menos pode ser chamado de sintaxe de consulta neste ORM - é muito específico, usando geradores, lambdas e outros pães de linguagem Python.
query = select(c for c in Customer if sum(o.total_price for o in c.orders) > 1000) Product.select().order_by(lambda p: desc(sum(p.order_items.quantity))).first()
Essa abordagem requer uma certa quebra do cérebro.
Tartaruga orm

Examinando vários repositórios que permitem animais de estimação, encontrei uma coleção de testes de diferentes ORMs com medições de velocidade. Além do Pony ORM já mencionado, um certo Tortoise ORM apareceu na lista dos mais rápidos. É claro que os resultados dos testes dependem de quem os escreve e como eles são executados, mas você precisa examinar mais de perto isso.
Tartaruga é um projeto relativamente jovem, que ainda está em desenvolvimento ativo. O bom desempenho desta biblioteca é explicado pelo fato de que o ORM não contém nada supérfluo e está pronto para uso aprisionado por operação assíncrona. E também assume o uso do uvloop , que funciona mais rápido que os ciclos de eventos nativos dos pitons .
Esse ORM ainda é muito bruto para ser usado em combate (por exemplo, até que os pools de conexão sejam implementados), mas você deve observar o desenvolvimento dessa lib. Se tudo correr bem com os desenvolvedores, no próximo ano teremos um wrapper muito rápido para o banco de dados, com boa velocidade e sem sintaxe estranha no estilo do Pony.