Main Image
Imagen
Library over several levels with stair cases
03. Agosto 2022

Sincronizar datos de MS-SQL en Drupal

by Jürgen Haas

En un proyecto de ya existente, un cliente solicitó una nueva funcionalidad para una campaña de marketing que estaban a punto de lanzar: en su sistema ERP, mantienen una enorme lista de proyectos con muchas propiedades asociadas a ellos y una alta frecuencia de cambio de datos. Tanto los proyectos existentes se actualizan como los nuevos proyectos se añaden a la lista. Esos proyectos deben ser promocionados en su sitio Drupal, pero por supuesto, no tiene sentido mantener esos datos manualmente o incluso dos veces.

Para hacer esto un poco más desafiante, los datos no sólo deben ser mostrados en una vista. Eso habría sido posible con una base de datos secundaria configurada para el sitio de Drupal y diciéndole al Views que consulte esa base de datos externa para el contenido. En su lugar, cada uno de los proyectos también debe venir con una página de aterrizaje que muestra más detalles y un formulario de contacto para que los visitantes puedan enviar fácilmente su interés en él.

Sólo hay un enfoque razonable para esto: cada proyecto en la base de datos remota necesita convertirse en una entidad de contenido en Drupal.

¿No es suficiente desafío todavía? Entonces déjame decirte que la base de datos externa es MS-SQL alojada en Azure. Como si toda esa infraestructura y herramientas de Microsoft fuera lo que los queridos ingenieros de Drupal quisiéramos acercarnos. Pero esa es otra historia.

Definiendo la pila de soluciones

Como el requisito principal tiene que ver con la sincronización de contenidos y la creación de entidades en Drupal, sólo hay una respuesta para ello: El módulo migrate del núcleo de Drupal. Esto puede ser una sorpresa para algunos, pero ese conjunto de módulos no sólo es capaz de realizar migraciones puntuales de, por ejemplo, Drupal 7 a 9. Migrate es una excelente herramienta para leer datos de una fuente externa, procesar los datos y almacenarlos en Drupal - no sólo una vez, sino tantas veces como sea necesario, y contiene todos los mecanismos necesarios para reconocer los registros de datos existentes y tal vez actualizados. Mencionar que también incluye una sólida función de reversión es sólo para hacer el cuadro completo, no porque sea necesario para este proyecto actual.

Eso nos dejó con el requisito de hablar con una base de datos MS-SQL y, una vez resuelto, dejar que migrate acepte una base de datos SQL como fuente de datos para toda su magia. Siguiendo el viejo dicho "Hay un módulo para eso", hemos tenido la suerte de encontrar uno para cada uno de los dos requisitos:

Equipado con esos 3 componentes, la implementación resultó ser extremadamente sencilla.

Pasos de implementación

Una vez que hemos descargado y habilitado los módulos extra, primero definimos la base de datos extra en el archivo settings.php existente del sitio Drupal:

$databases['azure']['default'] = [
  'database' => 'customer365projects',
  'username' => 'DrupalServiceUser',
  'password' => 'PASSWORD',
  'prefix' => '',
  'host' => 'sqlcustomer365.database.windows.net',
  'port' => '1433',
  'namespace' => 'Drupal\sqlsrv\Driver\Database\sqlsrv',
  'autoload' => 'modules/contrib/sqlsrv/src/Driver/Database/sqlsrv',
  'driver' => 'sqlsrv',
];

Eso es todo lo que necesitas hacer, asumiendo que el host de la base de datos es accesible desde el host de Drupal a través de TCP/IP. Si ese no es el caso, que es muy probable, entonces su TI tiene que establecer un túnel con SSH o una VPN desde el host de Drupal al host de la base de datos. Pero eso está más allá del alcance de esta entrada del blog.

A partir de ahora, su sitio Drupal puede "hablar" con esa base de datos MS-SQL en Azure. No es que esto fuera necesario para nuestro proyecto, pero para dar una idea de lo que tendrías que hacer si quisieras escribir código personalizado para leer y/o escribir desde o hacia esa base de datos:

$database = \Drupal\Core\Database\Database::getConnection('default', 'azure');
$query = $database->select('...');

El último paso para nosotros fue configurar el módulo migrate para importar los datos de esta base de datos. Hemos creado una configuración de migrate así:

id: projects
label: Projects
migration_dependencies: { }
source:
  plugin: custom_sql_query
  key: azure
  keys:
    - id
  sql_query: "SELECT *
        FROM projects p
                 INNER JOIN extras e
                            ON p.id = e.id
        WHERE p.status='for-drupal'"
destination:
  plugin: entity:node
  default_bundle: project
process:
  title: project
  updated: timestamp
  field_a: property_a
  field_b: property_b
  field_c: property_c

Esta es una versión simplificada de la configuración para mostrar los bloques de construcción importantes de esta solución. Por supuesto, se puede facilitar toda la potencia de la para procesar los datos y almacenarlos en la base de datos por defecto de Drupal.

Los ajustes clave para hablar con nuestra base de datos externa en esta configuración son la fuente plugin, key y sql_query. El plugin custom_sql_query proviene del módulo instalado, la clave azure hace referencia a la clave que hemos utilizado en la configuración para esa base de datos y la consulta SQL es totalmente a tu gusto y depende del modelo de datos de tu base de datos externa.

Entonces, ¿qué es lo siguiente?

drush migrate:import projects

Y ya has terminado. De verdad!

Conclusión

Un conjunto bastante complejo de requisitos se resuelve con sólo dos módulos de contribución de drupal.org y dos configuraciones en la configuración de Drupal y para el módulo de migración del núcleo de Drupal. No se requiere código personalizado. Y sin embargo, el cliente ahora puede ejecutar el comando migrate:import con un crontab del sistema cada 5 minutos. Todos los datos del proyecto de su sistema ERP interno aparecen en el sitio de Drupal, siempre precisos y actualizados. No hay nada mejor.

Tools

Añadir nuevo comentario