Exécuter des requêtes SQL depuis Pandas
Exécutez des instructions SELECT arbitraires avec pd.read_sql_query et paramétrez les requêtes de manière sûre pour éviter les injections SQL.
Exécuter des requêtes SQL depuis Pandas est une leçon Pandas & NumPy Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Pandas & NumPy Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Pandas & NumPy Academy comprend 4 leçons au total.
pd.read_sql : l'interface unifiée
Pandas fournit trois fonctions de lecture SQL : pd.read_sql() (interface générique), pd.read_sql_table() (lit une table complète à partir de son nom) et pd.read_sql_query() (exécute du SQL arbitraire). Pour la plupart des traitements analytiques, pd.read_sql_query() est la plus puissante, car elle vous permet d'écrire n'importe quelle instruction SELECT avec filtrage, jointures et agrégation avant que les données n'atteignent Pandas. Utiliser SQL pour les opérations lourdes et Pandas pour l'analyse finale est souvent plus efficace que de tout charger et de filtrer en Python.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///ecommerce.db')
# Three equivalent patterns
df1 = pd.read_sql('SELECT * FROM orders LIMIT 100', con=engine)
df2 = pd.read_sql_table('orders', con=engine) # full table
df3 = pd.read_sql_query('SELECT * FROM orders LIMIT 100', con=engine)
print(df3.head())
print(df3.columns.tolist())Filtrer au niveau de la base de données
Filtrez toujours les données en SQL plutôt que de tout charger et de les filtrer dans Pandas. Une base de données correctement indexée peut exécuter une clause WHERE sur des millions de lignes et n'en renvoyer que quelques milliers en quelques millisecondes, tandis que Pandas devrait d'abord charger plusieurs gigaoctets de données. La règle d'or : transmettre les prédicats à la base de données. Utilisez WHERE pour filtrer les lignes, SELECT col1, col2 pour sélectionner les colonnes et LIMIT pendant le développement afin d'afficher rapidement un aperçu des résultats.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
# Filter and project at SQL level — only fetch what you need
query = '''
SELECT order_id, customer_id, amount, status
FROM orders
WHERE status = 'completed'
AND order_date >= '2024-01-01'
AND amount > 50
LIMIT 1000
'''
df = pd.read_sql_query(query, con=engine)
print(f'Rows: {len(df)}, Columns: {list(df.columns)}')Agréger en SQL ou dans Pandas
Pour les récapitulatifs simples par groupe sur de grandes tables, les agrégations SQL sont plus performantes que Pandas, car le moteur de base de données peut utiliser les index, l'exécution parallèle et l'agrégation par hachage sur disque. Utilisez SQL avec GROUP BY et SUM/COUNT/AVG lorsque la table est volumineuse. Chargez le résultat agrégé (un petit DataFrame) dans Pandas pour poursuivre l'analyse, la visualisation ou la combinaison avec d'autres données. Pour les agrégations personnalisées complexes que SQL ne peut pas exprimer, chargez un sous-ensemble filtré dans Pandas et utilisez-y groupby.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
# Aggregate in SQL — returns a small result set
query = '''
SELECT region,
COUNT(*) AS order_count,
ROUND(SUM(amount), 2) AS total_revenue,
ROUND(AVG(amount), 2) AS avg_order_value
FROM orders
WHERE status = 'completed'
GROUP BY region
ORDER BY total_revenue DESC
'''
df = pd.read_sql_query(query, con=engine)
print(df)JOIN dans les requêtes SQL
Les opérations SQL JOIN sont plus efficaces que merge() de Pandas pour les jointures sur de grandes tables, car la base de données peut utiliser des recherches indexées. Écrivez votre jointure en SQL et recevez dans Pandas un résultat préalablement joint et éventuellement filtré. Pour les analyses portant sur plusieurs tables, une seule requête SQL avec plusieurs JOIN est généralement plus rapide que la lecture séparée de chaque table suivie d'une fusion dans Pandas, en particulier lorsqu'une table contient des millions de lignes et que la jointure réduit considérablement le résultat.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///ecommerce.db')
query = '''
SELECT o.order_id,
c.customer_name,
c.country,
p.product_name,
o.amount
FROM orders o
JOIN customers c ON o.customer_id = c.id
JOIN products p ON o.product_id = p.id
WHERE o.status = 'completed'
LIMIT 500
'''
df = pd.read_sql_query(query, con=engine)
print(df.head())Utiliser des variables Python dans les requêtes
Pour intégrer des variables Python à des requêtes SQL en toute sécurité, utilisez text() de SQLAlchemy avec des paramètres nommés. Définissez des espaces réservés avec :param_name dans la chaîne de requête et transmettez un dictionnaire à l'argument params de read_sql_query. Cette méthode fonctionne pour les valeurs uniques et, avec certaines bases de données, pour les listes. Évitez les chaînes interpolées f ou le formatage avec % pour construire des chaînes de requête à partir de variables : ces méthodes sont dangereuses, même en interne.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
# Python variables to inject
min_amount = 200.0
start_date = '2024-01-01'
end_date = '2024-12-31'
query = sa.text('''
SELECT * FROM orders
WHERE amount > :min_amount
AND order_date BETWEEN :start_date AND :end_date
''')
with engine.connect() as conn:
df = pd.read_sql_query(query, con=conn,
params={'min_amount': min_amount,
'start_date': start_date,
'end_date': end_date})
print(f'{len(df)} orders found')Utiliser des CTE et des sous-requêtes
Les analyses complexes nécessitent souvent des expressions de table communes (CTE) ou des sous-requêtes. Elles sont entièrement prises en charge par pd.read_sql_query : transmettez simplement l'intégralité du SQL comportant plusieurs clauses comme chaîne de requête. Les CTE (introduites avec le mot-clé WITH) rendent les requêtes complexes plus lisibles en donnant un nom aux résultats intermédiaires. Elles sont utiles pour calculer des totaux cumulés, effectuer des classements au sein de groupes et appliquer des filtrages en plusieurs étapes qui seraient verbeux dans Pandas.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
query = '''
WITH monthly_revenue AS (
SELECT strftime('%Y-%m', order_date) AS month,
SUM(amount) AS revenue
FROM orders
WHERE status = 'completed'
GROUP BY month
)
SELECT month,
revenue,
revenue - LAG(revenue) OVER (ORDER BY month)
AS month_over_month_change
FROM monthly_revenue
ORDER BY month
'''
df = pd.read_sql_query(query, con=engine)
print(df.tail())Lire avec un DatetimeIndex
Lors de la lecture de données chronologiques depuis une base de données, définissez la colonne d'horodatage comme index du DataFrame en transmettant index_col='date_column' et parse_dates=['date_column'] à read_sql_query. Vous obtenez ainsi directement un DatetimeIndex, ce qui permet d'effectuer des extractions temporelles dans Pandas (df['2024-01']), du rééchantillonnage et des calculs glissants sans étapes supplémentaires de post-traitement. L'argument parse_dates indique à Pandas de convertir la colonne en datetime64.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///metrics.db')
df = pd.read_sql_query(
'SELECT recorded_at, metric_value FROM daily_metrics ORDER BY recorded_at',
con=engine,
index_col='recorded_at',
parse_dates=['recorded_at']
)
print(df.index.dtype) # datetime64[ns]
print(df['2024-06']) # Slice by month directlyAnalyser les performances des requêtes lentes
Lorsqu’une requête est lente, ajoutez le mot-clé SQL EXPLAIN (ou EXPLAIN QUERY PLAN dans SQLite) avant votre SELECT afin d’afficher le plan d’exécution de la base de données. Recherchez les analyses complètes de tables ('SCAN TABLE') là où vous vous attendriez à des recherches utilisant un index ('SEARCH TABLE'). L’absence d’index sur les colonnes utilisées dans WHERE et JOIN est la cause la plus fréquente des requêtes lentes. Créez l’index approprié dans la base de données, puis vérifiez de nouveau avec EXPLAIN avant de relancer la chaîne de traitement Pandas.
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
# Check if the query uses an index
with engine.connect() as conn:
plan = conn.execute(sa.text(
'EXPLAIN QUERY PLAN SELECT * FROM orders WHERE customer_id = 42'
)).fetchall()
for row in plan:
print(row)
# Look for 'SEARCH TABLE orders USING INDEX' — not 'SCAN TABLE'Pagination des grands ensembles de résultats
Lorsque vous parcourez interactivement un grand ensemble de résultats (par exemple, en traitant une page de résultats à la fois), utilisez LIMIT et OFFSET en SQL pour mettre en œuvre la pagination. Récupérez N lignes à la fois, traitez-les, puis récupérez les N suivantes. Bien que cette méthode soit moins efficace que l’approche avec chunksize (qui conserve un curseur), la pagination est utile lorsque les lignes doivent être affichées progressivement dans un rapport ou lorsque vous combinez les résultats de plusieurs requêtes.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
page_size = 10000
offset = 0
while True:
query = sa.text(
'SELECT * FROM orders ORDER BY order_id LIMIT :limit OFFSET :offset'
)
with engine.connect() as conn:
df = pd.read_sql_query(query, con=conn,
params={'limit': page_size, 'offset': offset})
if len(df) == 0:
break
print(f'Page at offset {offset}: {len(df)} rows')
offset += page_sizeCombiner des requêtes SQL avec la logique Pandas
Le modèle le plus puissant est une chaîne de traitement hybride : utilisez SQL pour le filtrage et l’agrégation à gros grain, puis Pandas pour les transformations détaillées que SQL exprime difficilement (tableaux croisés, analyse de chaînes, fonctions apply, fenêtres glissantes). Lisez depuis SQL un ensemble de résultats de taille raisonnable (quelques milliers de lignes), puis enchaînez les opérations Pandas sur le DataFrame obtenu. Vous combinez ainsi les points forts des deux outils tout en faisant circuler les données dans un seul processus Python.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
# SQL: coarse filter and join
df = pd.read_sql_query('''
SELECT o.customer_id, o.amount, o.order_date, c.country
FROM orders o JOIN customers c ON o.customer_id = c.id
WHERE o.status = 'completed'
''', con=engine, parse_dates=['order_date'])
# Pandas: rolling 30-day revenue per country
df = df.sort_values('order_date')
df['rolling_30d'] = (
df.groupby('country')['amount']
.transform(lambda x: x.rolling('30D').sum())
)
print(df.head())Gestion des erreurs des requêtes de base de données
Les requêtes de base de données peuvent échouer en raison de délais d’attente du réseau, d’erreurs de syntaxe ou de connexions perdues. Entourez les appels à la base de données de blocs try-except qui interceptent sqlalchemy.exc.OperationalError pour les problèmes de connexion et sqlalchemy.exc.ProgrammingError pour les erreurs de syntaxe SQL. Consignez l’erreur avec son contexte (requête, paramètres), puis effectuez une nouvelle tentative avec un délai croissant ou gérez l’échec proprement. Dans les chaînes de traitement de production, il est essentiel de distinguer les erreurs temporaires (qui peuvent être retentées) des erreurs permanentes (qui nécessitent de corriger le SQL).
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
try:
df = pd.read_sql_query(
'SELECT * FROM nonexistent_table',
con=engine
)
except sa.exc.OperationalError as e:
print(f'Connection or table error: {e}')
except sa.exc.ProgrammingError as e:
print(f'SQL syntax error: {e}')
except Exception as e:
print(f'Unexpected error: {type(e).__name__}: {e}')Vérification rapide
Vérifiez votre compréhension des concepts d’analyse de données présentés dans cette leçon.
Récapitulatif de la leçon
Dans cette leçon, vous avez appris que pd.read_sql_query() exécute tout SELECT SQL et renvoie un DataFrame, que le fait de déporter les filtres et les agrégations vers SQL est plus efficace que de charger des tables entières dans Pandas, et que les chaînes de traitement hybrides combinent SQL pour réduire les données à gros grain avec Pandas pour les transformations personnalisées détaillées. Nous allons maintenant apprendre à réécrire des DataFrames dans des tables de base de données.
Apprends Python avec un tuteur IA — gratuit
Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.
- Cours
- 30
- Leçons
- 120
Questions Fréquemment Posées
La leçon « Exécuter des requêtes SQL depuis Pandas » est-elle gratuite ?
Oui — le texte complet de « Exécuter des requêtes SQL depuis Pandas » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Pandas & NumPy Academy, passe à CoddyKit PRO. Le cours Pandas & NumPy Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Exécuter des requêtes SQL depuis Pandas » ?
Exécutez des instructions SELECT arbitraires avec pd.read_sql_query et paramétrez les requêtes de manière sûre pour éviter les injections SQL. Tu pratiques Pandas & NumPy Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Pandas & NumPy Academy ?
Aucune expérience préalable n'est requise. Pandas & NumPy Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « Exécuter des requêtes SQL depuis Pandas » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Pandas & NumPy Academy ?
Oui. Chaque leçon Pandas & NumPy Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Se connecter à une base de données avec SQLAlchemy
- Exécuter des requêtes SQL depuis Pandas
- Écrire des DataFrames dans des tables de base de données
- Pandas ou SQL : choisir le bon outil