{"meta":{"title":"Refactorisation des couches d’accès aux données","intro":"Copilot Chat peut suggérer des façons de dissocier votre code d’accès aux données de votre logique métier, ce qui facilite la maintenance et la mise à l’échelle d’une application.","product":"GitHub Copilot","breadcrumbs":[{"href":"/fr/copilot","title":"GitHub Copilot"},{"href":"/fr/copilot/tutorials","title":"Tutoriels"},{"href":"/fr/copilot/tutorials/copilot-cookbook","title":"livre de recettes GitHub Copilot"},{"href":"/fr/copilot/tutorials/copilot-cookbook/refactor-code","title":"Refactoriser le code"},{"href":"/fr/copilot/tutorials/copilot-cookbook/refactor-code/refactor-data-access-layers","title":"Restructurer les couches d'accès aux données"}],"documentType":"article"},"body":"# Refactorisation des couches d’accès aux données\n\nCopilot Chat peut suggérer des façons de dissocier votre code d’accès aux données de votre logique métier, ce qui facilite la maintenance et la mise à l’échelle d’une application.\n\nLes requêtes SQL codées en dur et le code d'accès aux données étroitement couplé peuvent rendre difficile la mise à l’échelle ou le changement de bases de données, et mènent souvent à une répétition de logique.\n\nCopilot Chat peut recommander l’implémentation d’un modèle de référentiel ou d’une couche d’accès aux données qui extrait les interactions de base de données, ce qui rend le code plus modulaire et réduit la redondance. Il peut également aider à remanier les requêtes SQL pour en faire des versions optimisées, améliorant ainsi les performances et la maintenabilité.\n\n> \\[!NOTE] Les réponses décrites dans cet article sont des exemples.\n> Copilot Chat les réponses ne sont pas déterministes. Vous pouvez donc obtenir des réponses différentes des réponses présentées ici.\n\n## Exemple de scénario\n\nCe code Python se connecte à une base de données SQLite, récupère un enregistrement utilisateur et retourne les données utilisateur. Toutefois, elle ne parvient pas à abstraction de la logique de connexion de base de données et utilise une requête codée en dur vulnérable à l’injection SQL.\n\n```python id=database-connection\nimport sqlite3\n\ndef get_user_by_id(user_id):\n    conn = sqlite3.connect('database.db')\n    cursor = conn.cursor()\n    cursor.execute(f\"SELECT display_name FROM users WHERE id = {user_id}\")\n    user = cursor.fetchone()\n    conn.close()\n    return user\n```\n\n## Exemple d'invite 1\n\nVous pouvez commencer par poser Copilot une question générale sur la façon d’améliorer le code.\n\n```copilot copy prompt ref=database-connection\nHow can I improve this code to make it safe and easier to update and expand? List possible improvements but don't show revised code.\n```\n\n## Exemple de réponse 1\n\nCopilot propose plusieurs suggestions pour améliorer le code :\n\n* Abstraire les détails de la connexion à la base de données.\n* Utilisez des requêtes paramétrables pour empêcher l’injection SQL.\n* Utilisez un gestionnaire de contexte pour vous assurer que la connexion de base de données est correctement fermée si une erreur se produit.\n* Ajouter la gestion des erreurs.\n\n## Exemples d’invite 2\n\nVous pouvez utiliser la réponse à votre première invite pour écrire une invite plus spécifique.\n\n```copilot copy prompt ref=database-connection\nRewrite this code to make it more scalable and easier to maintain. Use a context manager. Avoid hardcoded SQL queries and tightly coupled data access code. Instead, use a repository pattern to abstract database interactions and make the code more modular and reusable. Where possible optimize the code to improve performance. Include error trapping, and make sure the code is not vulnerable to SQL injection.\n```\n\n## Exemple de réponse 2\n\nCopilot suggère de fractionner le code en fichiers distincts, chacun avec un objectif spécifique. Il fournit également un exemple de code pour renvoyer les détails d’un utilisateur.\n\nLes modifications suggérées implémentent un modèle de référentiel et utilisent des requêtes paramétrables pour éviter l’injection SQL.\n\n```python\n# database.py\nimport sqlite3\n\nclass Database:\n    def __init__(self, db_path):\n        self.db_path = db_path\n\n    def __enter__(self):\n        self.conn = sqlite3.connect(self.db_path)\n        self.cursor = self.conn.cursor()\n        return self\n\n    def __exit__(self, exc_type, exc_val, exc_tb):\n        if exc_type or exc_val or exc_tb:\n            self.conn.rollback()\n        else:\n            self.conn.commit()\n        self.conn.close()\n\n# user_repository.py\nclass UserRepository:\n    def __init__(self, db):\n        self.db = db\n\n    def get_user_by_id(self, user_id):\n        try:\n            self.db.cursor.execute(\"SELECT display_name FROM users WHERE id = ?\", (user_id,))\n            user = self.db.cursor.fetchone()\n            return user\n        except sqlite3.Error as e:\n            print(f\"An error occurred: {e}\")\n            return None\n\n# main.py\nfrom database import Database\nfrom user_repository import UserRepository\n\ndef get_user_by_id(user_id):\n    with Database('database.db') as db:\n        user_repo = UserRepository(db)\n        return user_repo.get_user_by_id(user_id)\n\n# Example usage\nif __name__ == \"__main__\":\n    user = get_user_by_id(1)\n    if user:\n        print(user)\n    else:\n        print(\"User not found or an error occurred.\")\n```\n\nLe code révisé améliore l’original de plusieurs façons :\n\n* Le code implémente désormais une couche d’accès aux données de base.\n* La classe `Database` gère la connexion à la base de données SQLite, implémentant le protocole de gestionnaire de contexte avec les méthodes `__enter__` et `__exit__` . Cela garantit que la connexion de base de données est correctement gérée, notamment la validation des transactions et la fermeture de la connexion.\n* La classe `UserRepository` encapsule la logique d’accès aux données utilisateur.\n* Les valeurs des requêtes sont paramétrées pour empêcher l’injection SQL.\n* Les erreurs sont interceptées, avec des détails affichés sur la console.\n\n## Lectures complémentaires\n\n* [Ingénierie rapide pour GitHub Copilot Chat](/fr/copilot/concepts/prompting/prompt-engineering)\n* [Meilleures pratiques pour l’utilisation de GitHub Copilot](/fr/copilot/get-started/best-practices)"}