¿Por qué mi importación de base de datos está perdiendo datos de widgets de texto?
He creado un sitio en WordPress en nuestra máquina de desarrollo. En el tema que estamos usando hay numerosas zonas de widgets para mostrar texto (barra lateral y página principal). He utilizado widgets de Texto simples en todas estas zonas para colocar nuestra información de visualización.
Cuando migré el sitio a producción, utilicé el plugin WP-DB-Backup para tomar una instantánea de la base de datos. Luego edité el archivo .sql resultante para actualizar todas las rutas de archivos y referencias URL para que apunten a nuestro sitio de producción.
Después de crear la base de datos, el sitio web y copiar todos los archivos al sitio de producción, ejecuto el archivo .sql desde la línea de comandos de mysql para importar los datos a la nueva base de datos.
Sin embargo, cuando voy al sitio de producción, algunos textos aparecen y otros no. Cuando reviso la sección de widgets del sitio, los widgets de texto faltan en algunas de las zonas de widgets. Los widgets de texto ni siquiera son visibles en la zona de "Widgets Inactivos", simplemente no están ahí.
Incluso he intentado repetir el proceso usando el plugin BackWPup, notando que la sintaxis SQL es diferente cuando exporta la base de datos.
¿Por qué estoy perdiendo datos de widgets de texto durante la importación?

Aquí es donde está tu problema:
Luego edité el archivo .sql resultante para actualizar todas las rutas de archivos y referencias de URL para que apunten a nuestro sitio de producción.
No puedes hacer eso. WordPress almacena muchas opciones como "datos serializados", que contienen tanto el contenido de las cadenas como su longitud. Así que cuando modificas la URL y la longitud cambia, los datos serializados ya no son correctos y PHP los rechaza.
El problema a largo plazo es que, básicamente, lo estás haciendo mal. Si estás configurando un sitio de desarrollo cuyos datos serán migrados, entonces debería tener exactamente la misma URL que tu sitio de producción desde el principio. Puedes editar manualmente tu archivo HOSTS para asignar a ese dominio de producción (como ejemplo.com) una dirección IP diferente (como 127.0.0.1) y así la URL "de producción" se convertirá en el sitio de desarrollo, solo para ti. Luego puedes crear tus datos, enlaces y todo lo demás usando esa URL de producción, y cuando migres los datos, no tendrás que alterar nada.
A corto plazo, sin embargo, no uses un simple buscar/reemplazar en el archivo SQL. Como has descubierto, esto rompe cosas.
Y aunque dudo en sugerirlo, hay una manera de alterar el código núcleo de WordPress para manejar estas serializaciones rotas. Debes modificar el archivo wp-includes/functions.php y cambiar la función maybe_unserialize() por esto:
function maybe_unserialize( $original ) {
if ( is_serialized( $original ) ) {
$fixed = preg_replace_callback(
'!(?<=^|;)s:(\d+)(?=:"(.*?)";(?:}|a:|s:|b:|i:|o:|N;))!s',
'serialize_fix_callback',
$original );
return @unserialize( $fixed );
}
return $original;
}
function serialize_fix_callback($match) { return 's:' . strlen($match[2]); }
Esta NO es una solución viable a largo plazo. Solo debe usarse para que puedas funcionar ahora mismo. A largo plazo, necesitas corregir tu proceso de desarrollo para que no tengas que hacer este tipo de modificaciones de URL en primer lugar.

@Otto excelente respuesta. Una pregunta rápida, ¿modificar una tabla de blob/texto no serializada como wp_posts fuera de MySql afectaría alguno de los datos serializados en wp_post_meta o wp_options? Tuve el mismo problema con el widget de texto pero no toqué wp_options, solo modifiqué wp_posts.

¡Guau, nunca me di cuenta de que eso era lo que estaba pasando con los datos, pero tiene mucho sentido! ¡Muchas gracias!

Esta NO es una solución viable a largo plazo. - ni siquiera a corto plazo.

Interesante; ¿cómo se edita el archivo hosts para apuntar example.com a localhost 127.0.0.1?

Si deseas hacerlo en tu máquina local, simplemente encuentra tu archivo hosts y agrega una entrada allí (consulta superuser.com para encontrar los detalles específicos de tu sistema operativo). De lo contrario, pídele a tu administrador de Operaciones o Red que agregue una entrada en el controlador de dominio.

Otra solución alternativa que algunas personas usan es hacer que su sistema de desarrollo tenga un nombre de dominio "example.dev" en lugar de "example.com". De esa manera, las longitudes no cambian para las cadenas cuando las mueven a producción. Prefiero el método del archivo HOSTS.

@songdogtech - Agrega una nueva línea en el archivo hosts 127.0.0.1 example.com
, el archivo se encuentra en C:\WINDOWS\system32\drivers\etc\hosts
..(asumiendo la ruta de instalación predeterminada). Nota: Xampp y aplicaciones similares usualmente agregan hosts virtuales en este archivo, por lo que probablemente ya tendrás algunas entradas allí.

¡Esto no es realmente una solución, sino más bien un truco! También hay escenarios que no te permiten cambiar el archivo host. Por ejemplo, detrás de un proxy corporativo empresarial o si tienes https en producción y http en desarrollo.

2016 y WordPress sigue guardando datos serializados en la base de datos. El premio al código más famoso y peor escrito
no tiene que buscar más lejos.

¡¡¡MUCHAS GRACIAS!!! Buen punto y gran truco. Generalmente uso este truco para recuperar todos los datos y luego simplemente actualizo la configuración existente nuevamente, y cuando elimino este código funciona perfectamente.

Para solucionar este problema siempre utilizo la herramienta WordPress Serialized Search & Replace que se proporciona aquí. Funciona perfectamente sin ningún problema. La he estado usando durante mucho tiempo en todos los requisitos de migración de mis sitios. Esto se encarga de los problemas al migrar la base de datos de desarrollo a producción.
https://interconnectit.com/search-and-replace-for-wordpress-databases/

Me funcionó la mayoría de las veces. Pero esta semana cuando reemplacé http://localhost/Me/site_name
por http://site.dev
(de un host local a otro) usando la versión 3.0.0, extrañamente perdí las posiciones de mis widgets y menús. Así que quizás este problema también esté relacionado con la longitud de la cadena.

He estado usándolo... pero nunca me he enfrentado a esta situación hasta ahora. ¿Puedes descargar la versión anterior de este script e intentarlo nuevamente con esa? Prueba reemplazando localhost/Me/site_name
con site.dev
.

La URL ha cambiado (ahora es https en lugar de http): https://interconnectit.com/products/search-and-replace-for-wordpress-databases/

Script fantástico. Dupliqué una base de datos MySQL desde PHPMyAdmin de una antigua a una nueva -sin cambiar ninguna URL-, luego fui a la carpeta del nuevo sitio donde estaban los archivos frescos de WP (junto con un wp-config.php apropiado, con las nuevas credenciales de la base de datos), añadí el script, y se encargó de todo. Los datos serializados se actualizan junto con las URLs normales. ¡Fácil y rápido! Muy recomendado. Importante: ¡no olvides eliminar el script después de usarlo ya que tiene acceso a los detalles de tu base de datos!

La respuesta de Otto es acertada. También descubrí esto por las malas.
Sin embargo, logré solucionarlo usando un script genial en http://spectacu.la/search-and-replace-for-wordpress-databases/
Para migrar tu WordPress a una nueva URL o nombre de dominio, haz lo siguiente:
- Haz un volcado de la base de datos (por ejemplo usando phpMyAdmin) del WordPress existente
- Restaura el volcado tal cual (sin necesidad de modificaciones) en tu nueva ubicación
- Descomprime el script de spectacu.la en la carpeta principal de WordPress (no es un plugin...)
- Ejecuta el script en tu nuevo sitio accediendo desde el navegador, ej. http://nuevo-sitio.url/searchreplacedb.php
- No olvides eliminar el script de la carpeta principal de tu nuevo WordPress

Sé que esto es un poco antiguo, pero ¿dónde se supone que debo especificar el nuevo nombre de la base de datos si estoy restaurando el volcado tal cual? ¿No debería al menos poner el nuevo nombre de la base de datos en el segundo paso? Gracias por esta información

No estoy seguro de entender completamente tu pregunta. La restauración de la base de datos se puede hacer con herramientas como phpmyadmin y puedes darle un nombre nuevo o usar el antiguo. El script que mencioné simplemente cambia el texto dentro de la base de datos después de que ya se ha restaurado.

Hola Yoav, gracias por la respuesta. Me refiero a que cuando exporto una BD normalmente cambio el nombre de la base de datos al nuevo y modifico los enlaces del dominio. Dicho esto, en tu paso número dos dices restaurar el volcado tal cual sin modificaciones, solo quería saber si es literal o si al menos debo cambiar el nombre de la base de datos. Sé que puede ser una pregunta tonta, pero estoy un poco perdido. Gracias de nuevo por tu respuesta.

No sé cómo haces el volcado de tu base de datos, pero si usas la herramienta de 'exportar' de phpmyadmin, entonces no importa cuál sea el nombre de la base de datos. Puedes usar la exportación e importarla de vuelta a cualquier otra base de datos. En general, con respecto al punto número 2, creo que está bien cambiar el nombre de la base de datos.

El OP fue demasiado entusiasta al realizar una búsqueda y reemplazo en el archivo de exportación de la base de datos, y terminó cambiando ocurrencias de "wp_" dentro de algunos de los datos serializados. La solución es ser más parsimonioso en la búsqueda y reemplazo incluyendo el acento grave en la expresión regular, y luego actualizar manualmente las claves restantes dentro de la base de datos después de la importación.
Si estás migrando y cambiando el prefijo, y prefieres un enfoque más manual, haz lo siguiente (esto solo aborda las preocupaciones del OP y no trata con la actualización de la URL del sitio)
- Haz una copia de seguridad y mueve tu archivo de exportación de la base de datos SQL al nuevo entorno (mi ejemplo asume un nombre de archivo como backup_AAAA-MM-DD.sql)
- Realiza una búsqueda y reemplazo masivo en el archivo SQL para cambiar los nombres de las tablas a usar tu nuevo prefijo (ANTES de importar tu archivo SQL!). Una forma de hacer esto sería usando un comando Perl de una línea como: perl -p -i.bak -e "s/`wp_/`miprefijo_/g" backup_AAAA-MM-DD.sql
- Importa tus datos SQL a la base de datos
- Actualiza cualquier clave dentro de _options que contenga el prefijo codificado:
update miprefijo_options set option_name = concat('miprefijo_',substr(option_name,4)) where option_name like 'wp_%'
- Actualiza cualquier clave dentro de _user_meta que contenga el prefijo codificado:
update miprefijo_usermeta set meta_key = concat('miprefijo_',substr(meta_key,4)) where meta_key like 'wp_%'

Utilicé el plugin WP Migrate, que reemplaza las rutas http y de carpetas. Tuve un único problema al importar, pero lo resolví agregando las siguientes líneas al inicio del archivo SQL generado:
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
También probé con la herramienta Search And Replace (v2.1) mencionada por @Yoav, pero sigue dañando mis datos serializados.

Hola Ricardo, ¡Bienvenido a WordPress Answers! El área donde publicaste está reservada para respuestas a la pregunta original. Aunque tu pregunta está relacionada, deberías publicarla como una pregunta separada. De esa manera tendrás muchas más posibilidades de que te la respondan.
