[PYTHON] Comment INNER JOIN avec SQL Alchemy

J'étais accro parce que je n'avais pas beaucoup d'informations, alors je vais prendre une note.

Cette fois, je vais montrer un exemple d'INNER JOIN en utilisant l'exemple de table fourni par MySQL.

MySQL :: MySQL Documentation: Other MySQL Documentation Obtenez les exemples de données à partir du lien à droite de la base de données de ménagerie sur la page ci-dessus et chargez-les.

La méthode de chargement sur MySQL est omise. Le contenu des exemples de données est constitué de deux tableaux contenant chacun 10 et 9 enregistrements.

mysql> show tables;
+---------------------+
| Tables_in_menagerie |
+---------------------+
| event               |
| pet                 |
+---------------------+
2 rows in set (0.01 sec)

mysql> select * FROM event;
+----------+------------+----------+-----------------------------+
| name     | date       | type     | remark                      |
+----------+------------+----------+-----------------------------+
| Fluffy   | 1995-05-15 | litter   | 4 kittens, 3 female, 1 male |
| Buffy    | 1993-06-23 | litter   | 5 puppies, 2 female, 3 male |
| Buffy    | 1994-06-19 | litter   | 3 puppies, 3 female         |
| Chirpy   | 1999-03-21 | vet      | needed beak straightened    |
| Slim     | 1997-08-03 | vet      | broken rib                  |
| Bowser   | 1991-10-12 | kennel   | NULL                        |
| Fang     | 1991-10-12 | kennel   | NULL                        |
| Fang     | 1998-08-28 | birthday | Gave him a new chew toy     |
| Claws    | 1998-03-17 | birthday | Gave him a new flea collar  |
| Whistler | 1998-12-09 | birthday | First birthday              |
+----------+------------+----------+-----------------------------+
10 rows in set (0.00 sec)

mysql> select * FROM pet;
+----------+--------+---------+------+------------+------------+
| name     | owner  | species | sex  | birth      | death      |
+----------+--------+---------+------+------------+------------+
| Fluffy   | Harold | cat     | f    | 1993-02-04 | NULL       |
| Claws    | Gwen   | cat     | m    | 1994-03-17 | NULL       |
| Buffy    | Harold | dog     | f    | 1989-05-13 | NULL       |
| Fang     | Benny  | dog     | m    | 1990-08-27 | NULL       |
| Bowser   | Diane  | dog     | m    | 1979-08-31 | 1995-07-29 |
| Chirpy   | Gwen   | bird    | f    | 1998-09-11 | NULL       |
| Whistler | Gwen   | bird    | NULL | 1997-12-09 | NULL       |
| Slim     | Benny  | snake   | m    | 1996-04-29 | NULL       |
| Puffball | Diane  | hamster | f    | 1999-03-30 | NULL       |
+----------+--------+---------+------+------------+------------+
9 rows in set (0.00 sec)

L'histoire de SQL Alchemy d'ici. J'ai souvent voulu faire ce genre de connexion. (Au fait, `` litière '' signifie donner naissance à un animal)

mysql> SELECT event.name, event.date, event.type, event.remark, pet.species  
        FROM event INNER JOIN pet ON event.name = pet.name
        WHERE event.type ='litter';
+--------+------------+--------+-----------------------------+---------+
| name   | date       | type   | remark                      | species |
+--------+------------+--------+-----------------------------+---------+
| Fluffy | 1995-05-15 | litter | 4 kittens, 3 female, 1 male | cat     |
| Buffy  | 1993-06-23 | litter | 5 puppies, 2 female, 3 male | dog     |
| Buffy  | 1994-06-19 | litter | 3 puppies, 3 female         | dog     |
+--------+------------+--------+-----------------------------+---------+
3 rows in set (0.00 sec)

Comment exprimer cela dans SQL Alchemy est la suivante.

   #Créer une instance de chaque table
   events = Table('event', metadata, autoload=True)
   pets = Table('pet', metadata, autoload=True)

   #:Créez une liste de colonnes que vous souhaitez obtenir
   columns = [events, pets.c.species]

    #: join()Spécifiez la table et la condition avec lesquelles vous souhaitez joindre select()Appel
    q = join(events, pets, events.c.name == pets.c.name) \
        .select() \
        .where(events.c.type == 'litter')
    #:Enfin avec_only_columns()Passez la liste des colonnes auxquelles vous souhaitez accéder
    q =  q.with_only_columns(columns)

with_only_columns () est utilisé pour affiner les champs à obtenir.

Ensuite, créez la requête suivante comme exemple de requête qui utilise count () à l'aide de GROUP BY.

mysql> SELECT event.name, count(event.name) AS litter_count 
       FROM event INNER JOIN pet ON event.name = pet.name 
       WHERE event.type = 'litter' GROUP BY event.name;

+--------+--------------+
| name   | litter_count |
+--------+--------------+
| Buffy  |            2 |
| Fluffy |            1 |
+--------+--------------+
2 rows in set (0.00 sec)
    #: func.count()Spécifiez les colonnes à agréger avec
    #: AS litter_nombre d'étiquettes('litter_count')Spécifié par
    columns = [events.c.name, func.count(events.c.name).label('litter_count')]

    q = join(events, pets, events.c.name == pets.c.name) \
        .select() \
        .where(events.c.type == 'litter') \
        .group_by(events.c.name)  # <=Ajouter une ligne à la requête précédente
    q =  q.with_only_columns(columns)

Le code plus court serait:

    q =  select(events.c.name == pets.c.name) \
        .where(events.c.type == 'litter') \
        .group_by(events.c.name)
    q =  q.with_only_columns(columns)

La condition de jointure a été déplacée dans select () sans join ().

Avec SQLAlchemy, vous pouvez écrire des requêtes en utilisant INNER JOIN, GROUP BY et COUNT () avec juste autant de code.

C'est une histoire difficile, mais au moment où je suis arrivé ici, j'ai lu divers documents et finalement fait cette requête. SQLAlchemy est si riche en fonctionnalités que vous devriez lire la documentation une fois avant de l'utiliser sérieusement. Je n'avais pas beaucoup d'informations en japonais, j'ai donc lu et étudié Stack Overflow et d'autres sites en anglais. Si vous utilisez Python, c'est difficile si vous ne parlez pas anglais. Pour Ruby, il y a beaucoup d'informations japonaises grâce à Rails, mais Python n'est pas populaire au Japon, donc j'ai l'impression qu'il y a peu de savoir-faire.

Je pense qu'il faudra beaucoup de temps pour comprendre une fois, mais une fois que je l'ai compris, je me suis rendu compte que c'est une bibliothèque assez puissante. J'étudie toujours, donc je ne pense pas que le style d'écriture ci-dessus soit toujours le meilleur, et il devrait y avoir un meilleur style d'écriture qui soit plus lisible.

J'ai vu de nombreux documents que SQLAlchemy utilise comme ORM, mais j'aime utiliser SQLAlchemy comme générateur de requêtes pour les instructions SELECT.

Plutôt que de créer une bibliothèque de votre propre générateur de requêtes dans un projet et de le rendre impossible J'ai trouvé beaucoup plus facile pour tout le monde d'étudier et d'utiliser SQL Alchemy.

sample.py


#!/usr/bin/env python2.7
# -*- coding:utf-8 -*-

from sqlalchemy import create_engine, MetaData, Table
from sqlalchemy.sql import select, join, func

from pprint import pprint

config = {
    'user': 'user',
    'passwd':'password',
    'host': 'localhost',
    'port': 3306,
    'database': 'menagerie',
}
dsn_fmt = 'mysql+pymysql://%(user)s:%(passwd)s@%(host)s:%(port)d/%(database)s'
dsn = dsn_fmt % config

engine = create_engine(dsn, echo=True)

metadata = MetaData(bind=engine)

events = Table('event', metadata, autoload=True)
pets = Table('pet', metadata, autoload=True)

if __name__ == '__main__':
    #: part1
    columns = [events, pets.c.species]
    q = join(events, pets, events.c.name == pets.c.name) \
        .select().where(events.c.type == 'litter')
    q =  q.with_only_columns(columns)
    print q
    for row in q.execute():
        pprint(dict(row))

    #: part2
    columns = [events.c.name, func.count(events.c.name).label('litter_count')]
    q = join(events, pets, events.c.name == pets.c.name) \
        .select() \
        .where(events.c.type == 'litter') \
        .group_by(events.c.name)
    q =  q.with_only_columns(columns)
    print q
    for row in q.execute():
        pprint(dict(row))

    #: part2 another version
    q =  select(events.c.name == pets.c.name) \
        .where(events.c.type == 'litter') \
        .group_by(events.c.name)
    q =  q.with_only_columns(columns)
    print q
    for row in q.execute():
        pprint(dict(row))

Recommended Posts

Comment INNER JOIN avec SQL Alchemy
Comment mettre à jour avec SQLAlchemy?
Comment modifier avec SQLAlchemy?
Comment supprimer avec SQLAlchemy?
Comment obtenir l'identifiant du parent avec sqlalchemy
Comment utiliser SQLAlchemy / Connect avec aiomysql
Introduction à RDB avec sqlalchemy Ⅰ
Comment lancer avec Theano
Comment séparer les chaînes avec ','
Comment faire RDP sur Fedora31
Comment convertir un objet de classe en dictionnaire avec SQLAlchemy
Comment obtenir plus de 1000 données avec SQLAlchemy + MySQLdb
Comment gérer une session dans SQLAlchemy
Python: comment utiliser async avec
Connectez-vous à plusieurs bases de données avec SQL Alchemy
Pour utiliser virtualenv avec PowerShell
Comment installer python-pip avec ubuntu20.04LTS
Comment gérer les données déséquilibrées
Introduction à RDB avec sqlalchemy II
Comment démarrer avec Scrapy
Comment démarrer avec Python
Comment gérer l'erreur DistributionNotFound
Comment démarrer avec Django
Comment calculer la date avec python
Comment installer mysql-connector avec pip3
Comment installer Anaconda avec pyenv
Comment effectuer un traitement arithmétique avec le modèle Django
Comment titrer plusieurs figures avec matplotlib
Comment ajouter un package avec PyCharm
Comment utiliser OpenVPN avec Ubuntu 18.04.3 LTS
Comment utiliser Cmder avec PyCharm (Windows)
Comment empêcher les mises à jour de paquets avec apt
Comment utiliser BigQuery en Python
Comment utiliser Ass / Alembic avec HtoA
Comment gérer les erreurs de compatibilité d'énumération
Comment utiliser le japonais avec le tracé NLTK
Comment faire un test de sac avec python
Comment rechercher Google Drive dans Google Colaboratory
Comment afficher le japonais python avec lolipop
Comment télécharger des vidéos YouTube avec youtube-dl
Comment utiliser le notebook Jupyter avec ABCI
Comment mettre hors tension de Linux sur Ultra96-V2
Comment utiliser la commande CUT (avec exemple)
Comment entrer le japonais avec les malédictions Python
Comment installer zsh (avec la personnalisation .zshrc)
Comment lire les données de problème avec Paiza
Comment regrouper des volumes avec LVM
Comment installer python3 avec docker centos
Comment utiliser le pilote JDBC avec Redash
Comment supprimer sélectivement les anciens tweets avec Tweepy
Comment télécharger avec Heroku, Flask, Python, Git (4)
Comment gérer les fuites de mémoire dans matplotlib.pyplot
Comment créer des exemples de données CSV avec hypothèse