El objetivo de este artículo es, a través de la biblioteca mostrar herramientas que permiten facilitar considerablemente el proceso de desarrollo de bases de datos en proyectos PHP que utilizan el SGBD PostgreSQL.
La información de este artículo será especialmente útil para desarrolladores que desean aprovechar al máximo las capacidades de PostgreSQL, pero se enfrentan a problemas de mantenimiento de la lógica de negocio que se ha trasladado a la base de datos.
Este artículo no describirá las ventajas o desventajas de almacenar la lógica de negocio en la base de datos. Se asume que el lector ya ha tomado esta decisión.
Se abordarán las siguientes cuestiones:
- ¿En qué formato almacenar el volcado de la estructura de la base de datos en el sistema de control de versiones (en adelante VCS)?
- ¿Cómo rastrear cambios en la estructura de la base de datos después de guardar el volcado?
- ¿Cómo trasladar los cambios en la estructura de la base de datos a otros entornos sin conflictos y con archivos de migración reducidos?
- ¿Cómo establecer el proceso de trabajo paralelo en el proyecto entre varios desarrolladores?
- ¿Cómo desplegar de manera segura una mayor cantidad de cambios en la estructura de la base de datos en el entorno de producción?
SchemaKeeper está diseñado para trabajar con procedimientos almacenados escritos en el lenguaje . No se ha probado con otros lenguajes, por lo que su uso puede no ser tan eficiente o incluso ser imposible.
¿En qué formato almacenar el volcado de la estructura de la base de datos en VCS?
La biblioteca proporciona la función saveDump, que guarda la estructura de todos los objetos de la base de datos como archivos de texto separados. Se crea un directorio que contiene la estructura de la base de datos, dividida en archivos agrupados que son fáciles de agregar al VCS.
Consideremos la conversión de objetos de la base de datos a archivos a través de varios ejemplos:
Tipo de objeto
Esquema
Nombre
Ruta relativa al archivo
Tabla
public
accounts
./public/tables/accounts.txt
Procedimiento almacenado
public
auth(hash bigint)
./public/functions/auth(int8).sql
Representación
booking
tariffs
./booking/views/tariffs.txt
El contenido de los archivos es una representación textual de la estructura de un objeto de la base de datos en particular. Por ejemplo, para los procedimientos almacenados, el contenido del archivo será la definición completa del procedimiento almacenado, que comienza con el bloque CREATE OR REPLACE FUNCTION.
Como se puede ver en la tabla anterior, la ruta al archivo contiene información sobre el tipo, el esquema y el nombre del objeto. Este enfoque facilita la navegación por el volcado y la revisión del código de los cambios en la base de datos.
Extensión
.sqlpara archivos con código fuente de procedimientos almacenados, se seleccionó para que el IDE proporcione automáticamente herramientas para interactuar con la base de datos al abrir el archivo.
¿Cómo rastrear cambios en la estructura de la base de datos después de guardar el volcado?
Al guardar el volcado de la estructura actual de la base de datos en VCS, obtenemos la posibilidad de verificar si se han realizado cambios en la estructura de la base de datos después de crear el volcado. En la biblioteca para identificar cambios en la estructura de la base de datos existe la función verifyDump, que sin efectos secundarios devuelve información sobre las diferencias.
Un método alternativo de verificación es llamar nuevamente a la función saveDump, especificando el mismo directorio, y verificar en VCS la existencia de cambios. Dado que todos los objetos de la base de datos se han guardado en archivos separados, VCS mostrará solo los objetos que han cambiado.
La principal desventaja de este método es la necesidad de sobrescribir archivos para ver los cambios.
¿Cómo trasladar los cambios en la estructura de la base de datos a otros entornos sin conflictos y con archivos de migración reducidos?
Gracias a la función deployDump el código fuente de los procedimientos almacenados puede ser editado exactamente igual que el código fuente normal de la aplicación. Se pueden agregar/eliminar nuevas líneas en el código de los procedimientos almacenados y enviar los cambios al sistema de control de versiones de inmediato, o crear/eliminar procedimientos almacenados mediante la creación/eliminación de los archivos correspondientes en el directorio del volcado.
Por ejemplo, para crear un nuevo procedimiento almacenado en el esquema public es suficiente crear un nuevo archivo con la extensión .sql en el directorio public/functions, colocar en él el código fuente del procedimiento almacenado, incluyendo el bloque CREATE OR REPLACE FUNCTION, y luego llamar a la función deployDump. De manera similar, se realiza la modificación y eliminación del procedimiento almacenado. De este modo, el código llega tanto a VCS como a la base de datos.
Si en el código fuente de algún procedimiento almacenado aparece un error, o un desajuste entre el nombre del archivo y el procedimiento almacenado, entonces deployDump no se ejecutará, mostrando el texto del error. La desincronización de los procedimientos almacenados entre el volcado y la base de datos actual es imposible al utilizar deployDump.
Al crear un nuevo procedimiento almacenado, no es necesario introducir manualmente el nombre correcto del archivo. Basta con que el archivo tenga la extensión
.sql. Después de llamar adeployDumpel texto del error contendrá el nombre correcto, que se puede utilizar para renombrar el archivo.
deployDump permite modificar los parámetros de la función o el tipo de retorno sin acciones adicionales, mientras que en el enfoque clásico habría que
primero ejecutar DROP FUNCTION, y solo después CREATE OR REPLACE FUNCTION.
Desafortunadamente, existen algunas situaciones en las que deployDump no se pueden aplicar los cambios automáticamente. Por ejemplo, si se elimina una función desencadenante que está siendo utilizada por al menos un desencadenador. Estas situaciones se resuelven manualmente mediante archivos de migración.
Si la transferencia de cambios en los procedimientos almacenados es responsabilidad del propio , para transferir los demás cambios en la estructura es necesario utilizar archivos de migración. Por ejemplo, una buena biblioteca para trabajar con migraciones es .
Las migraciones deben aplicarse antes de ejecutar deployDump. Esto permite hacer todos los cambios en la estructura y resolver situaciones problemáticas, para que los cambios en los procedimientos almacenados se transfieran sin problemas posteriormente.
Trabajar con migraciones se describirá más en los siguientes apartados.
¿Cómo establecer el proceso de trabajo paralelo en el proyecto entre varios desarrolladores?
Es necesario crear un script de inicialización completa de la base de datos, que será ejecutado por el desarrollador en su máquina de trabajo, alineando la estructura de la base de datos local con el volcado guardado en VCS. Lo más fácil es dividir la inicialización de la base de datos local en 3 pasos:
- Importar el archivo con la estructura básica, que se llamará, por ejemplo,
base.sql - Aplicación de migraciones
- mountsnoop.py
deployDump
base.sql— este es el punto de partida, sobre el cual se aplican las migraciones y se ejecutadeployDump, es decir, elbase.sql + migraciones + deployDump = estructura actual de la base de datos. Este archivo se puede generar utilizando la herramientapg_dump. Se utilizabase.sqlexclusivamente al inicializar la base de datos desde cero.
Llamaremos al script de inicialización completa de la base de datos refresh.sh. El proceso de trabajo puede verse de la siguiente manera:
- El desarrollador ejecuta en su entorno
refresh.shy obtiene la estructura actual de la base de datos - El desarrollador comienza a trabajar en la tarea asignada, modificando la base de datos local para las necesidades de la nueva funcionalidad (
ALTER TABLE ... ADD COLUMNetc.) - Después de completar la tarea, el desarrollador invoca la función
saveDump, para registrar en VCS los cambios realizados en la base de datos - El desarrollador vuelve a ejecutar
refresh.sh, luegoverifyDump, que ahora muestra la lista de cambios para incluir en la migración - El desarrollador transfiere todos los cambios de estructura a un archivo de migración, ejecuta una vez más
refresh.shyverifyDump, y, si la migración se ha elaborado correctamente,verifyDumpmostrará que no hay diferencias entre la base de datos local y el volcado guardado.
El proceso descrito anteriormente es compatible con los principios de gitflow. Cada rama en el VCS contendrá su versión del volcado, y durante la fusión de ramas se realizará la fusión de volcadones. En la mayoría de los casos, después de la fusión no es necesario tomar medidas adicionales, pero si se hicieron cambios en diferentes ramas, por ejemplo, en una misma tabla, puede surgir un conflicto.
Consideremos una situación conflictiva con el siguiente ejemplo: hay una rama develop, de la cual se han ramificado dos ramas: feature1 y feature2, que no tienen conflictos con develop, pero tienen conflictos entre sí. La tarea es realizar la fusión de ambas ramas en develop. Para tal caso, se recomienda primero fusionar una de las ramas en develop, y luego fusionar develop en la rama restante, resolviendo los conflictos en la última rama, después de lo cual se realizará la fusión de la última rama en develop. En la etapa de resolución de conflictos puede que sea necesario corregir el archivo de migración en la última rama, para que coincida con el volcado final, que incluye los resultados de las fusiones.
¿Cómo desplegar de manera segura una mayor cantidad de cambios en la estructura de la base de datos en el entorno de producción?
Gracias a la presencia de un volcado de la estructura actual de la base de datos en el VCS, surge la posibilidad de verificar la base de datos de producción para garantizar que coincide exactamente con la estructura requerida. Esto asegura que todos los cambios que los desarrolladores habían pensado se han trasladado exitosamente a la base de datos de producción.
Dado que en PostgreSQL es , se recomienda seguir el siguiente orden de despliegue, para que, en caso de un error imprevisto, se realice un ROLLBACK:
- Iniciar la transacción
- En la transacción, realizar todas las migraciones
- En esta misma transacción, llevar a cabo
deployDump - Sin finalizar la transacción, ejecutar
verifyDump. Si no hay errores, ejecutarCOMMIT. Si hay errores, ejecutarROLLBACK
Estos pasos se pueden integrar fácilmente en los enfoques existentes para el despliegue de aplicaciones, incluyendo zero-downtime.
Conclusión
Gracias a los métodos descritos anteriormente, se puede extraer el máximo rendimiento de los proyectos "PHP + PostgreSQL", sacrificando relativamente poco en términos de comodidad de desarrollo en comparación con la implementación de toda la lógica de negocio en el código principal de la aplicación. Además, el procesamiento de datos en a menudo se presenta de forma más transparente y requiere menos código que la misma funcionalidad escrita en PHP.
Fuente: habr.com
