23 noviembre 2007

Mysql con python (migración de UNB a phpBB)

Esta entrada está relacionada con ésta otra cómo migrar los usuarios de UNB forms a phpBB.

Para terminar con la migración del foro de UNB a phpBB aprovechamos para recordar cómo se puede acceder desde Pyhon a MySQL.

En nuestro caso el usuario solicitaba darse de alta, pero no utilizábamos el sistema del foro, por lo cual del usuario sólo sabíamos la dirección de correo electrónico.

Lo que tenemos que migrar es el nombre de usuario y la dirección de correo electrónico de registro, pero tenemos que hacer tres comprobaciones de datos que no existen en la base de datos nueva; la dirección de correo como nombre de usuario, la dirección de correo como dirección de email como email
registrado, el nombre de usuario como nombre de usuario.

Lo primero que hacemos es exportar los datos que necesitamos de la base de datos de UNB, para ello ejecutamos esta sentencia en MySQL:


mysql> SELECT  Name, RegEmail, Password  INTO outfile 'lista' FIELDS TERMINATED BY ';'from unb1_Users ;


Una vez que tenemos la lista de nombres la copiamos al directorio de trabajo donde tengamos el script migracion.py que es el script que vamos a utilizar para migrar los datos.

El script es el siguiente:

#!/usr/bin/env python

# importamos el modulo MySQLdb
import MySQLdb
# importamos el modulo string poder pasar a minusculas los strings
import string


# Definimos una funcion en la que definimos una consulta simple a la base de datos


def ConsultaSql(consulta, dato):
cursor.execute("SELECT "+consulta+" FROM phpbb_users WHERE "+consulta+"=\""+string.lower(dato)+"\"")
result=cursor.fetchone()
if (result):
return True
else:
return False

# Definimos la funcion en con la que relizaremos las inserciones pertinentes en la base de datos

def InsercionSql(nombre, correo, contras):
cursor.execute("SELECT user_id from phpbb_users")
numcolumnas=int(cursor.rowcount)
numid=int(numcolumnas)+1
print numid
cursor.execute("INSERT INTO phpbb_users(user_id, user_active, username, user_password, user_regdate, user_level, user_style, user_email) VALUES (%s,1,%s,%s,1194441299,0,8,%s)", (numid, nombre, contras, correo))
cursor.execute("INSERT INTO phpbb_user_group(group_id, user_id, user_pending) VALUES (5,%s,0)", (numid))
cursor.execute("INSERT INTO phpbb_user_group(group_id, user_id, user_pending) VALUES (6,%s,0)", (numid))


# Conexion a la base de datos
db = MySQLdb.connect(host="localhost", user="jose",passwd="pruebas",db="pruebas")

# Creamos un cursor
cursor=db.cursor()

# Abrimos el fichero donde tenemos los valores exportados de la base de datos
fichero=open("lista")

# Creamos una lista con las lineas del fichero
leerfichero=fichero.readlines()

# iteramos sobre la lista
for linea in leerfichero:
# Ponemos lo que extraemos en minusculas para tenerlo todo igual y suprimimos el salto de linea del final
# Ademas creamos una lista por linea que contiene los tres valores
lineasinfin=string.lower(linea.rstrip('\n')).split(";")

# Iteramos para ver que ninguno de los valores esta insertado en la base de datos, si no estan llamamos a la funcion de ejecucion
for elemento in lineasinfin:
if(ConsultaSql("user_email", elemento)):
break
elif (ConsultaSql("username", elemento)):
break
else:
InsercionSql(lineasinfin[0],lineasinfin[1],lineasinfin[2])



Para poder ejecutarlo necesitamos el módulo MySQLdb de Python que no viene por defecto en la distribución.

Vamos a explicar paso a paso el script:

 1 #!/usr/bin/env python
2
3 # importamos el modulo MySQLdb
4 import MySQLdb
5 # importamos el modulo string poder pasar a minusculas los strings
6 import string
7
8
9 # Definimos una funcion en la que definimos una consulta simple a la base de datos
10
11
12 def ConsultaSql(consulta, dato):
13 cursor.execute("SELECT "+consulta+" FROM phpbb_users WHERE "+consulta+"=\""+string.lower(dato)+"\"")
14 result=cursor.fetchone()
15 if (result):
16 return True
17 else:
18 return False



Obviamente en la primera línea llamamos al intérprete de Python y después en la línea 4 y 6 importamos los módulos que vamos a necesitar.

En la línea 12 definimos un función que va a necesitar que se le pasen dos valores. Esta función va a comprobar si el dato que hemos extraido del fichero está en la base de datos, en caso positivo devuelve verdadero, en caso negativo devuelve falso. La consulta la hemos realizado escapando las comillas para variable, en la siguiente función veremos que se puede incluir las variables en las sentencias SQL de la otra manera que permite Python.


 # Definimos la funcion en con la que relizaremos las inserciones pertinentes en la base de datos
21
22 def InsercionSql(nombre, correo, contras):
23 cursor.execute("SELECT user_id from phpbb_users")
24 numcolumnas=int(cursor.rowcount)
25 numid=int(numcolumnas)+1
26 print numid
27 cursor.execute("INSERT INTO phpbb_users(user_id, user_active, username, user_password, user_regdate, user_level, user_style, user_email) VALUES (%s,1,%s,% s,1194441299,0,8,%s)", (numid, nombre, contras, correo))
28 cursor.execute("INSERT INTO phpbb_user_group(group_id, user_id, user_pending) VALUES (5,%s,0)", (numid))
29 cursor.execute("INSERT INTO phpbb_user_group(group_id, user_id, user_pending) VALUES (6,%s,0)", (numid))



Definimos una función para insertar los datos necesarios. Una vez comparados los datos, insertamos los valores que necesitamos en los campos correspondientes. Aquí tenemos que pasar a la función los valores que vamos a insertar.

En la línea 24 contamos el número de columnas y luego en la 25 sumamos una, para poder poner el id correspondiente.
En la línea 27 podemos ver la otra manera de incluir las variables en las sentencias SQL, aunque tenemos que tener en cuenta una cosa, y es que aunque numid sea un entero, hay que llamarlo como si fuera un string, luego supongo que internamente se hace el cambio a la hora de insertar.


 # Conexion a la base de datos
33 db = MySQLdb.connect(host="localhost", user="jose", passwd= "pruebas" db="pruebas")
34 # creamos un cursor
35 cursor=db.cursor()
36
37 # Abrimos el fichero donde tenemos los valores exportados de la base de datos
38 fichero=open("lista")
39
40 # Creamos una lista con las lineas del fichero
41 leerfichero=fichero.readlines()



Creamos el cursor de MySQL, abrimos el fichero y metemos cada línea del fichero en una lista.

 # iteramos sobre  la lista
44 for linea in leerfichero:
45 # Ponemos lo que extraemos en minusculas para tenerlo todo igual y suprimimos el salto de linea del final
46 # Ademas creamos una lista por linea que contiene los tres valores
47 lineasinfin=string.lower(linea.rstrip('\n')).split(";")
48
49 # Iteramos para ver que ninguno de los valores esta insertado en la base de datos, si no estan llamamos a la funcion de ejecucion
50 for elemento in lineasinfin:
51 if(ConsultaSql("user_email", elemento)):
52 break
53 elif (ConsultaSql("username", elemento)):
54 break
55 else:
56 InsercionSql(lineasinfin[0],lineasinfin[1],lineasinfin[2])




Esta es la última parte, lo primero que hacemos es iterar sobre la lista para extraer cada línea.
Una vez extraida podemos ver en la línea 47 que ponemos todas los caracteres en minúscula, quitamos el fin de línea y creamos una nueva lista separando los datos que teníamos, pero eliminando el separador ";".

En la línea 50 volvemos a iterar, pero esta vez aplicamos las funciones con los datos obtenidos y de ese modo realizamos la inserción de datos.


Supongo que se puede hacer de otro modo, y seguramente más rápido, pero para mí ha sido una buena manera de familiarizarme un poco con el módulo MySQLdb.

1 comentario:

Anónimo dijo...
Este comentario ha sido eliminado por un administrador del blog.