{"meta":{"title":"Refactorización de capas de acceso a datos","intro":"Copilot Chat puede sugerir maneras de desacoplar el código de acceso a datos de la lógica de negocios, lo que facilita el mantenimiento y la escala de una aplicación.","product":"GitHub Copilot","breadcrumbs":[{"href":"/es/copilot","title":"GitHub Copilot"},{"href":"/es/copilot/tutorials","title":"Tutoriales"},{"href":"/es/copilot/tutorials/copilot-cookbook","title":"Recetario de GitHub Copilot"},{"href":"/es/copilot/tutorials/copilot-cookbook/refactor-code","title":"Refactorización de código"},{"href":"/es/copilot/tutorials/copilot-cookbook/refactor-code/refactor-data-access-layers","title":"Refactorización de capas de acceso a datos"}],"documentType":"article"},"body":"# Refactorización de capas de acceso a datos\n\nCopilot Chat puede sugerir maneras de desacoplar el código de acceso a datos de la lógica de negocios, lo que facilita el mantenimiento y la escala de una aplicación.\n\nLas consultas SQL codificadas de forma rígida y el código de acceso a datos estrechamente acoplado pueden dificultar el escalado o cambio de bases de datos y, a menudo, dan lugar a una lógica repetida.\n\nCopilot Chat puede recomendar la implementación de un patrón de repositorio o una capa de acceso a datos que abstrae las interacciones de la base de datos, lo que hace que el código sea más modular y reduzca la redundancia. También puede ayudar a refactorizar las consultas SQL en versiones optimizadas, lo que mejora el rendimiento y la capacidad de mantenimiento.\n\n> \\[!NOTE] Las respuestas descritas en este artículo son ejemplos.\n> Copilot Chat las respuestas son no deterministas, por lo que puede obtener respuestas diferentes de las que se muestran aquí.\n\n## Escenario de ejemplo\n\nEste código de Python se conecta a una base de datos de SQLite, recupera un registro de usuario y devuelve los datos del usuario. Sin embargo, no puede abstraer la lógica de conexión de la base de datos y se usa una consulta codificada de forma rígida que es vulnerable a la inyección de código 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## Ejemplo de solicitud 1\n\nPuede empezar haciendo Copilot una pregunta general sobre cómo mejorar el código.\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## Respuesta de ejemplo 1\n\nCopilot realiza varias sugerencias para mejorar el código:\n\n* Abstraiga los detalles de conexión de la base de datos.\n* Usa consultas con parámetros para evitar la inyección de código SQL.\n* Usa un administrador de contextos para asegurarte de que la conexión de la base de datos se cierre correctamente si se produce un error.\n* Agrega control de errores.\n\n## Ejemplo de mensaje 2\n\nPuedes usar la respuesta a la primera indicación para escribir una indicación más específica.\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## Respuesta de ejemplo 2\n\nCopilot sugiere dividir el código en archivos independientes, cada uno con un propósito específico. También proporciona código de ejemplo para devolver los detalles de un usuario.\n\nLos cambios sugeridos implementan un patrón de repositorio y usan consultas con parámetros para evitar la inyección de código 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\nEl código revisado mejora el original de varias maneras:\n\n* El código ahora implementa una capa de acceso a datos básica.\n* La clase `Database` controla la conexión a la base de datos SQLite e implementa el protocolo del administrador de contextos con los métodos `__enter__` y `__exit__`. Esto garantiza que la conexión de base de datos se administre correctamente, incluidos la confirmación de transacciones y el cierre de la conexión.\n* La clase `UserRepository` encapsula la lógica para acceder a los datos de usuario.\n* Los valores de las consultas se parametrizan para evitar la inyección de código SQL.\n* Se detectan errores y los detalles se imprimen en la consola.\n\n## Lectura adicional\n\n* [Ingeniería de mensajes para GitHub Copilot Chat](/es/copilot/concepts/prompting/prompt-engineering)\n* [Procedimientos recomendados para usar GitHub Copilot](/es/copilot/get-started/best-practices)"}