Migración de usuarios de Wordpress a Strapi
Cómo obtener datos de una tabla en “wp_users” y “wp_usermeta” para pasar dichos datos (de los usuarios) a Strapi.
Antes de comenzar, hay que tener en cuenta que existen 2 tablas a destacar: “wp_users”, la cual va a contener todos los datos genéricos de los usuarios (nombre, contraseña, email, etc.); y “wp_usermeta”, la cual va a contener los datos más específicos de los usuarios (teléfono, ciudad, etc.).
La tabla “wp_usermeta” tiene una columna “meta_key”, la cual indica el tipo de valor al que se hace referencia y una columna “meta_value” que es el valor correspondiente a la columna “meta_key”; esto es, si hay una fila que tiene en “meta_key” el valor “phone” (por poner un ejemplo, no tiene que ser este específicamente para referirse al teléfono), en la fila correspondiente a “meta_value” tendrá el valor del teléfono correspondiente del usuario.
Sin embargo, lo que se repite a lo largo de toda la tabla (“wp_usermeta”) es el campo “user_id”, haciendo referencia al usuario en cuestión (de “wp_users”) y repitiendo todo el rato cada campo “meta_key” (con diferentes valores) hasta englobar todos (una fila con un ID con el campo “meta_key” con valor “phone”; otra fila con el mismo ID con el campo “meta_key” con valor “city”, etc.).
Para obtener todos los datos correctamente (ya que con un solo SELECT solo podrías referenciar una fila específica), hay que ir juntando varios SELECT para obtener los resultados esperados.
Para obtener hasta 1000 registros (por defecto es el límite en SQL) de las tablas:
SELECT DISTINCT users.user_email AS username,(SELECT DISTINCT users.user_email FROM emergencias.wp_users AS users WHERE users.ID = usermeta.user_id) AS email,("") AS password,(SELECT DISTINCT usermeta.meta_value FROM emergencias.wp_usermeta AS usermeta WHERE usermeta.meta_key = "billing_phone" AND users.ID = usermeta.user_id) AS phone,(SELECT DISTINCT usermeta.meta_value FROM emergencias.wp_usermeta AS usermeta WHERE usermeta.meta_key = "billing_country" AND users.ID = usermeta.user_id) AS country,(SELECT DISTINCT usermeta.meta_value FROM emergencias.wp_usermeta AS usermeta WHERE usermeta.meta_key = "billing_city" AND users.ID = usermeta.user_id) AS city,(SELECT DISTINCT usermeta.meta_value FROM emergencias.wp_usermeta AS usermeta WHERE usermeta.meta_key = "billing_address_1" AND users.ID = usermeta.user_id) AS address,(SELECT DISTINCT usermeta.meta_value FROM emergencias.wp_usermeta AS usermeta WHERE usermeta.meta_key = "billing_postcode" AND users.ID = usermeta.user_id) AS postal_code,(SELECT DISTINCT usermeta.meta_value FROM emergencias.wp_usermeta AS usermeta WHERE usermeta.meta_key = "billing_nif" AND users.ID = usermeta.user_id) AS nif,(SELECT DISTINCT TRIM(CONCAT(usermeta.meta_value, " ", (SELECT DISTINCT usermeta.meta_value FROM emergencias.wp_usermeta AS usermeta WHERE usermeta.meta_key = "last_name" AND users.ID = usermeta.user_id))) FROM emergencias.wp_usermeta AS usermeta WHERE usermeta.meta_key = "first_name" AND users.ID = usermeta.user_id) AS name_last_name,(SELECT DISTINCT usermeta.meta_value FROM emergencias.wp_usermeta AS usermeta WHERE usermeta.meta_key = "billing_company" AND users.ID = usermeta.user_id) AS company,(2) AS roleFROM emergencias.wp_users AS usersINNER JOIN emergencias.wp_usermeta AS usermetaON users.ID = usermeta.user_idWHERE users.ID = usermeta.user_id AND (TRIM(users.user_email) NOT LIKE(""));A tener en cuenta en el script SQL:
- La contraseña (password) estará con un valor por defecto en blanco para estos casos.
- Es necesario agregar a cada campo que se solicita un alias (
'campo' AS 'nombre', siendo'campo'lo que se quiere obtener, y'nombre'el alias necesario que se quiera agregar) correspondiente a la columna/campo de la colección/base de datos de “User” de Strapi. Esto es, si para referirse al usuario en Strapi en la colección “User” está el campo “username”, pero el alias en SQL se pone comoAS usuario; a la hora de importar no se tendrá en cuenta (no dará error, mencionará como si se hubiera importado todo el archivo pero los que tengan este campo que no coincida con el de Strapi, no será así). - A la hora de establecer el “role”, se debe de poner ‘2’ para referirse a usuarios de tipo “Public” (correspondiente al ID del rol en Strapi). Si se decide poner “Public” como valor en vez de ‘2’, el usuario no tendrá ningún rol.
- Por defecto el número máximo de registros que se pueden obtener en SQL son 1000. Si se desea obtener más de manera sencilla, antes de acabar el script SQL, habría que añadir
LIMIT 'x', siendo'x'el número que se considera de registros máximos posibles (ejemplo: si se haceLIMIT 1500y te devuelve exactamente 1500 registros, se debería de probar con una cantidad más grande hasta encontrarse con una cantidad que no sea fija. Por ejemplo, si se haceLIMIT 2000y te devuelve 1589 registros, se podría llegar a entender que ya no hay más datos que obtener y que son los necesarios). - Si se quiere saber como juntar varios campos en un único alias, se puede mirar de referencia el ejemplo con el nombre completo (“name_last_name”, que será una combinación de “first_name” y “last_name”). En este caso, también se tiene en cuenta que puede ser posible que el campo “last_name” no tenga valor; y a la hora de concatenar (
CONCAT), se agrega un espacio en blanco. Para quitar los espacios en blanco (a la izquierda y derecha del resultado), hay que englobar toda la funciónCONCAT()con la funciónTRIM(). - Se usa
SELECT DISTINCTpara evitar registros duplicados. - Puede ocurrir que al hacer un
SELECT, se devuelva un registro con campos vacíos o null, así que se va a tomar de referencia el campo “email” ya que es obligatorio, y se establece una condición para comprobar que no es vacío (se asume que nunca es null, pero si que puede estar vacío).
-Para obtener más de 1000 registros (en este ejemplo son 2000) de las tablas:
SELECT DISTINCT users.user_email AS username,(SELECT DISTINCT users.user_email FROM emergencias.wp_users AS users WHERE users.ID = usermeta.user_id) AS email,("") AS password,(SELECT DISTINCT usermeta.meta_value FROM emergencias.wp_usermeta AS usermeta WHERE usermeta.meta_key = "billing_phone" AND users.ID = usermeta.user_id) AS phone,(SELECT DISTINCT usermeta.meta_value FROM emergencias.wp_usermeta AS usermeta WHERE usermeta.meta_key = "billing_country" AND users.ID = usermeta.user_id) AS country,(SELECT DISTINCT usermeta.meta_value FROM emergencias.wp_usermeta AS usermeta WHERE usermeta.meta_key = "billing_city" AND users.ID = usermeta.user_id) AS city,(SELECT DISTINCT usermeta.meta_value FROM emergencias.wp_usermeta AS usermeta WHERE usermeta.meta_key = "billing_address_1" AND users.ID = usermeta.user_id) AS address,(SELECT DISTINCT usermeta.meta_value FROM emergencias.wp_usermeta AS usermeta WHERE usermeta.meta_key = "billing_postcode" AND users.ID = usermeta.user_id) AS postal_code,(SELECT DISTINCT usermeta.meta_value FROM emergencias.wp_usermeta AS usermeta WHERE usermeta.meta_key = "billing_nif" AND users.ID = usermeta.user_id) AS nif,(SELECT DISTINCT TRIM(CONCAT(usermeta.meta_value, " ", (SELECT DISTINCT usermeta.meta_value FROM emergencias.wp_usermeta AS usermeta WHERE usermeta.meta_key = "last_name" AND users.ID = usermeta.user_id))) FROM emergencias.wp_usermeta AS usermeta WHERE usermeta.meta_key = "first_name" AND users.ID = usermeta.user_id) AS name_last_name,(SELECT DISTINCT usermeta.meta_value FROM emergencias.wp_usermeta AS usermeta WHERE usermeta.meta_key = "billing_company" AND users.ID = usermeta.user_id) AS company,(2) AS roleFROM emergencias.wp_users AS usersINNER JOIN emergencias.wp_usermeta AS usermetaON users.ID = usermeta.user_idWHERE users.ID = usermeta.user_id AND (TRIM(users.user_email) NOT LIKE(""))LIMIT 2000;A tener en cuenta a la hora de exportar el archivo JSON:
Para obtener los datos obtenidos desde la ejecución SQL en un archivo externo JSON, hay que ejecutar el script mencionado (el que se vaya a usar), y nos saldrán los registros. Justo encima de los registros (en el borde de la ventana que ha aparecido, entre la izquierda y el centro del borde), habrá un campo que ponga “Export:”, y habrá que hacer clic sobre el icono/botón que hay justo al lado, y elegir el tipo de formato (aparecerá una ventana, y la opción de formato se encontrará en la esquina inferior izquierda) que será en formato JSON.
Esto generará un fichero JSON con una estructura casi completa adecuada para Strapi, pero hay que añadir unos pocos datos que faltan.
A tener en cuenta a la hora de importar el archivo JSON:
Configuración adicional en el proyecto:
Antes de comenzar con los detalles del archivo JSON, hay que hacer una configuración adicional sobre el plugin de “Import Export entries”, para poder importar y exportar datos JSON (se asume que el plugin ya está instalado y configurado previamente con la configuración básica).
Debido a que se desea hacer una referencia a la colección predeterminada de “User” que viene con Strapi cuando se crea un proyecto; su configuración se encuentra en un archivo diferente. La ubicación del archivo es ( ” . ” significa el directorio base, es decir, el nombre del proyecto): ./src/extensions/users-permissions/content-types/user/schema.json.
Para poder hacer referencia al campo principal (sería el “id” aunque no es realmente el id interno, sino el que se toma como “campo único”), hay que añadir el siguiente código en el fichero anterior. Este código sirve si se introduce al principio o en el medio del archivo en cuestión; si se añade al final recordar quitar la coma. Se introduce como un campo “global” (entre la primera y última { } del archivo .JSON):
"pluginOptions": { "import-export-entries": { "idField": "username" } }En este caso, el valor es “username”, pero en realidad el valor puede ser cualquiera, ya que la línea 'idField': 'username' es una referencia a que el campo “attributes” (otro campo “global” del mismo archivo) tenga dicho valor (en este caso “username”).
Configuración adicional en el fichero JSON exportado:
A la hora de inspeccionar el archivo JSON exportado, los datos se verán así:
[ { "campo1" "valor1", "campo2": "valor2" }, { "campo1" "valor3", "campo2": "valor4" }]Para hacer referencia a la colección “User” de Strapi, hay que agregar lo siguiente al fichero JSON:
{ "version": 2, "data": { "plugin::users-permissions.user": [ { "campo1" "valor1", "campo2": "valor2" }, { "campo1" "valor3", "campo2": "valor4" }] }}En resumen, el archivo JSON generado tiene que estar englobado por:
{ "version": 2, "data": { "plugin::users-permissions.user": // sustituir este comentario por todo el contenido del archivo JSON }}“version” indica la versión JSON que usa el plugin de Strapi, y “data” indica a qué tabla se está haciendo referencia y qué datos se van a introducir.
Una vez realizados todos los pasos, simplemente habrá que ir a la colección “Users”, hacer clic sobre la opción “Import” (esquina superior derecha), y seleccionar la opción “Drag & drop your file into this area or browse for a file to upload”, seleccionar el archivo que se quiere subir con todos los pasos previos realizados, y finalizar haciendo clic en “Import”. Tras eso, la página se recargará sola o se puede recargar manualmente para observar los campos introducidos.
Programa de Python que transforma el resultado del SQL exportado a JSON a un JSON que entiende STRAPI
import jsonfrom datetime import datetime
# Leer datos desde un archivo JSON con la codificación correctawith open('data.json', 'r', encoding='utf-8') as file: rows = json.load(file)
address = {}users = {}
def process_address(row, incremental_id):
address_data_row = { "id": incremental_id, "line1": row['address'], "city": row['city'], "postal_code": row['postal_code'], "country": row['country'], "dni_nif": row['nif'] } address[incremental_id] = address_data_row
def process_user(row, incremental_id): user = { "id": incremental_id, "username": row['username'], "email":row['email'], "password": "Alebat12358", "name_last_name": row['name_last_name'], "role": 2, "origin": "wordpress", "phone": row['phone'], "confirmed": 1, "billing_address": [incremental_id], "user_address": [incremental_id]
} users[incremental_id] = user
def process_row(row, incremental_id):
process_user(row, incremental_id) process_address(row, incremental_id)
all_data = [process_row(row, idx + 1) for idx, row in enumerate(rows)]all_data = { "version": 2, "data": { "plugin::users-permissions.user": users, "address.billing-address": address, "address.user-address": address, }}
# Convertir a JSONjson_data = json.dumps(all_data, indent=4)
# Guardar el resultado en un nuevo archivo JSONwith open('processed_data.json', 'w', encoding='utf-8') as file: file.write(json_data)
print("Datos procesados y guardados en 'processed_data.json'")Esto devolverá un json nuevo que es el que tenemos que usar para meterlo en el strapi e importar los usuarios que vienen de wordpress