BandaAncha.eu

Comunidad de usuarios
de fibra, móvil y ADSL

widechartomultibyte al pasar campo blob de Firebird a varchar de MySQL

Traxtocado

Lo primero de todo, gracias por al menos leer esto y también por la ayuda.

Resulta que llevo tiempo usando una aplicación que alguien hizo en Delphi y ahora que tengo tiempo, decidí migrarla a Python. La base de datos de la aplicación original estaba en Firebird, pero yo usaré MySQL o MariaDB.

El problema que me encuentro es que la base de datos original tiene un campo blob (aunque ahí solo se guarda texto) e investigando un poco, he visto que cuando introduces el texto en el campo de la aplicación, antes de guardarlo en el campo de la tabla de la base de datos hace un widechartomultibyte y posteriormente para mostrarlo en la aplicación, hace un multibytetowidechart.

En la nueva base de datos quiero guardar el texto de ese campo en texto plano en un campo varchar. Pero es la primera vez que me encuentro con el widechartomultibyte y viceversa.

¿Alguien podría decirme como podría hacer el cambio por ejemplo de leer ese campo de la tabla en Python e introducirlo en en otro campo de la tabla en texto plano… o incluso me valdría con hacer un .sql con los insert, pero cambiando los datos de ese campo por texto plano.

Muchas gracias por la ayuda.

Un saludo,

Traxtocado

BocaDePez
BocaDePez

No me queda muy claro. ¿Quieres convertir el campo de blob a cadena? Y de ser así, ¿lo vas a hacer mientras está en firebird, o una vez lo hayas pasado a mysql? Porque son dos cosas distintas.

🗨️ 7
Traxtocado

Gracias por la respuesta.

Quiero convertir el campo blob a cadena, pero los datos del campo blob antes de ser insertados en la base de datos, le hacen un widecharttomultibyte, por lo que los datos son ilegibles.

Ahora mismo ya he hecho la conversión de firebird a MySQL, pero como digo, los datos son ilegibles, debería usar multibytetowidechart para poder leerlos.

Si la solución es hacerlo mientras están en firebird, podría hacerlo creando un nuevo campo en la base de datos y poniendo los datos allí en texto plano, no habría problema.

Realmente lo que quiero es solucionarlo, me da igual si en firebird y luego lo paso a MySQL o directamente en el MySQL.

Un saludo,

Traxtocado

🗨️ 6
BocaDePez
BocaDePez

stackoverflow.com/questions/948174/how-d…ext-in-mysql

Mira la llamada a MultiByteToWideChar y sabrás en qué charset está. Entonces puedes usar algo como lo de arriba para poder convertirlo. Si la columna se llama datos crea otra llamada datos_convertidos de tipo TEXT y haces algo en plan

UPDATE nombre_tabla SET datos_convertidos = CONVERT(datos USING cp1252);

Donde cp1252 es la codificación que tiene el BLOB

🗨️ 5
BocaDePez
BocaDePez

Bueno, donde he dicho TEXT puedes poner VARCHAR o lo que te salga de ahí.

🗨️ 4
Traxtocado
🗨️ 3
BocaDePez
BocaDePez
🗨️ 2
Traxtocado
🗨️ 1
BocaDePez
BocaDePez
vukits

a ver, antes de nada tienes que tener u data access object o DAO …

que haga de interfaz entre el código y la base de datos.

no me digas que tu código haces las queries directamente :P

🗨️ 1
Traxtocado

A ver…en la migración del programa quiero mejorar algunas cosas. El campo blob no sé por qué quien hizo el programa lo creó, porque realmente solo se almacena texto, no se suben archivos ni nada por el estilo en ese campo, de hecho un varchar hubiese sido más que suficiente.

Ahora, en esta nueva versión del programa, quiero mejorar esas cosas. Por lo tanto, no tiene sentido guardar datos en las tablas que no sean testo plano.

La migración de la base de datos firebird a MySQL la hice en python escribiendo directamente las queries… si, pero el programa en sí… como voy a alojarlo en un servidor privado, quería hacerlo más accesible y pensé en hacerlo web, es decir… PHP. Ahí estoy usando PDO, pero no quiero tener esos datos así en la base de datos, por eso había pensado en hacer la migración de datos (en python) de firebird a MySQL y a ser posible arregar ese "problema" para no tener que gestionar más ese tipo de datos y que en la base de datos quede todo en texto plano.

Por cierto… gracias por la respuesta vukits

vukits

de Python no sé mucho…

pero siendo texto… hay que establecer codificaciones y cosas así…

¿has mirado algo sobre encode/decode , utf8 , etc?

🗨️ 1
Traxtocado

Lo único que he visto es que widechartomultibyte es una librería de windows. Pero no sé como aplicarlo a mi script en Python o cualquier otro script para poder hacer la conversión o bien directamente en la base de datos (cualquiera de las dos) o en un fichero, aunque sea CSV.

Josh

Parece que lo único que hace widechartomultibyte es convertir la cadena de texto que ha introducido el user y que viene en charset UTF-16 al de la base de datos, que puede ser UTF-8.

Yo me centraría en averiguar el charset de lo que hay en el blob, ya que igual no tienes ni que hacer ninguna conversión para meterlo en un varchar UTF-8 de MySQL.

🗨️ 26
Traxtocado

Pues entonces seguro que el problema es mío, porque he estado mirando y se supone que si hago en python "string".decode('UTF-8') debería pasarlo a UFT-8 sin embargo esto es lo que obtengo:

captura.png

El código en teoría es muy simple:

cur.execute("select test from clients where ID = 1110")
cur.set_stream_blob('test')
readerA = cur.fetchone()[0]

with open(r'C:\prueba\1110-22.bin','wb') as f:
    data = readerA.encode()
    data = data.decode('utf-8')
    f.write(data.encode())

La frase almacenada usando la herramienta es: "chorizo con patatas"

El charset, al menos antes de hacer el cambio a multibyte es UFT-8

Gracias por tu respuesta Josh.

🗨️ 25
BocaDePez
BocaDePez

Algo mas se escapa (no pun intended), eso que aparece en la captura no es nada habitual, ni es utf-8 ni unicode ni problemas de endian ni na de na. Lo unico que encaja es el tamaño, a dos bytes por char, pero nada mas… ni las letras en su lugar ni nada… parece mas un checksum o md5 que datos

Visto lo visto, si puedes añadir una columna varchar y hacer la conversion in situ antes de exportar los datos te ira mejor que intentando leer esos blobs directamente.

🗨️ 1
Traxtocado

Coincido contigo… y creo que todo viene dado de que en python, para hacer la conexión se necesita especificar un charset y yo puse utf-8.

Después he intentado extraer esos datos en distintos charsets, ASCII, ISO-8859-1… pero todos dan error, solo con el UTF-8 puedo extraer algo de ese campo.

Voy a ver si puedo crear un campo directamente el firebird y hacerle el convert.

vukits

No me ha quedado claro si tienes el código fuente del aplicativo original (no, no nos lo compartas: P)

¿O estás haciendo ingeniería inversa?

🗨️ 22
Traxtocado

La base de datos de la aplicación la tengo, pero la aplicación en sí no la hice yo, por lo que obviamente no tengo el código fuente. He hecho un poco de ingeniería inversa para poder ver lo que comento delmultibytetowidechar

Lo que si tengo es el código fuente de la versión que estoy haciendo ahora

En la base de datos… todos los datos son accesibles menos ese y me resulta muy curioso… porque es el campo observaciones de la aplicación y solo admite texto. No entiendo muy bien por qué quien lo hizo… lo hizo así y yo la verdad de delphi… poco.

🗨️ 21
BocaDePez
BocaDePez
🗨️ 12
BocaDePez
BocaDePez
🗨️ 11
BocaDePez
BocaDePez
🗨️ 2
vukits
BocaDePez
BocaDePez
🗨️ 7
Traxtocado
🗨️ 6
BocaDePez
BocaDePez
BocaDePez
BocaDePez
🗨️ 4
Traxtocado
🗨️ 3
BocaDePez
BocaDePez
1
🗨️ 2
Traxtocado
🗨️ 1
BocaDePez
BocaDePez
1
vukits
🗨️ 7
Traxtocado
🗨️ 6
djnacho
🗨️ 2
Traxtocado
🗨️ 1
vukits
🗨️ 1