Python3, Repetición de categorías en la lista de artículos

  • Autor Autor webmaaron
  • Fecha de inicio Fecha de inicio
webmaaron

webmaaron

1
Zeta
Verificado
Verificación en dos pasos activada
Verificado por Whatsapp
¡Ha verificado su Paypal!
Verificado por Binance
Suscripción a IA
Buenas tardes,

A ver si alguien me puede iluminar por que me estoy volviendo un poco loco.

Esta es la función en cuestión:

Python:
def obtener_articulo_aleatorio(cursor, date, cat):
        if cat:
            query = "SELECT * FROM datos WHERE publicado = 0 AND date = '%s' AND categoria NOT IN (%s) ORDER BY RAND() LIMIT 1"
            categorias_string = ','.join(["'{}'".format(c) for c in cat])
            params = (date.today(), categorias_string)
        else:
            query = "SELECT * FROM datos WHERE publicado = 0 AND date = %s ORDER BY RAND() LIMIT 1"
            params = (date.today(),)
      
        cursor.execute(query, params)
        record = cursor.fetchone()
        
       if record is None and cat:
            cursor.execute("SELECT * FROM datos WHERE publicado = 0 AND date = %s ORDER BY RAND() LIMIT 1", (date.today(),))
            record = cursor.fetchone()
        return record

Tengo una serie de artículos en una base de datos de Mysql, estos tienen un campo publicado (0 no publicado, 1 publicado) y una categoría (Además de titulo etcs...)

Lo que hago es una vez que se publica un articulo guardo la categoría en una lista 'cat' y cuando se vaya a pedir el siguiente articulo, que sea de diferente categoría que los que están en la lista. (La lista tiene un máximo de cinco artículos).
Las categorías contienen algunas espacios y tildes.

El script básicamente si no hay una categoría en la lista, saca uno aleatorio. Si hay alguna categoría (que seria ya el segundo registro) debería ejecutar la consulta con el NOT IN para que no salga de las categorías de la lista. Y si no hay items que estén fuera de las categorías de la lista, saca uno aleatorio.

El caso es que esta repitiendo las categorías, es decir, en la lista guarda [`Casa, Casa'] cuando hay artículos de otras categorías. En cambio si pido que me haga el print por pantalla de la consulta SQL que envia, es correcta:

SQL:
SELECT * FROM datos WHERE publicado = 0 AND date = 2023-07-17 AND categoria NOT IN ('Casa y jardín','Casa y jardín') ORDER BY RAND() LIMIT 1


A ver si alguien me puede decir que estoy haciendo mal por que me estoy volviendo loco con esto.

Un saludo y gracias!
Aaron
 
veamos quieres una lista de 5 artículos y cada articulo que sea de una categoría diferente(que no se repitan).
pues solo usa una consulta con DISTINCT y listo.

por cierto creo que estas almacenando las categorías como un campo en la tabla de datos? esta mal. Tienes que normalizar a otra tabla y usa valores numéricos para la búsqueda, de esta manera optimizas el rendimiento de tu aplicación. Bueno al menos que trabajes con un pequeño dataset.
 
veamos quieres una lista de 5 artículos y cada articulo que sea de una categoría diferente(que no se repitan).
pues solo usa una consulta con DISTINCT y listo.

por cierto creo que estas almacenando las categorías como un campo en la tabla de datos? esta mal. Tienes que normalizar a otra tabla y usa valores numéricos para la búsqueda, de esta manera optimizas el rendimiento de tu aplicación. Bueno al menos que trabajes con un pequeño dataset.
No, igual no me explique bien.

Con distinc vas a obtener los que sean de categorías distintas pero no estas teniendo en cuenta que tienen que ser distintas a las anteriores enviadas, no van en bulk (de cinco como dices) si no de uno en uno por lo que distintc no vale. De ahí que las categorías utilizadas vengan en una lista, si no, para que la lista?

Si solicito un articulo y sale de la categoria A, el proximo articulo no puede ser de A. Si el siguiente articulo es de C, el tercer articulo no puede ser de A o de C.


Almacenar las categorías como campo, aquí, no esta mal. Son pocos registros en cambio son muchas consultas con distintas variaciones por lo que es mejor de esta manera.

Gracias por tu aporte.
 
No, igual no me explique bien.

Con distinc vas a obtener los que sean de categorías distintas pero no estas teniendo en cuenta que tienen que ser distintas a las anteriores enviadas, no van en bulk (de cinco como dices) si no de uno en uno por lo que distintc no vale. De ahí que las categorías utilizadas vengan en una lista, si no, para que la lista?

Si solicito un articulo y sale de la categoria A, el proximo articulo no puede ser de A. Si el siguiente articulo es de C, el tercer articulo no puede ser de A o de C.


Almacenar las categorías como campo, aquí, no esta mal. Son pocos registros en cambio son muchas consultas con distintas variaciones por lo que es mejor de esta manera.

Gracias por tu aporte.

????
 

????
Es que nada tiene que ver eso.

Como te digo no se sacan todas las consultas de golpe.

Ahora saca un articulo.
Dentro de X minutos saca otro articulo y no puede ser de la misma categoria que el primero.
Dentro de X minutos saca otro articulo y no puede ser de la misma categoria que los dos primeros.

Y no se puede sacar y dejar almacenado por que puede haber por el medio modificaciones y que un articulo deje de estar disponible en el tiempo desde que se saca la primera consulta hasta que se va a entregar el ultimo.
 
De donde sacas la informacion de cat?
 
De donde sacas la informacion de cat?

Cada vez que se extrae un articulo y se publica (en otra función), una vez publicado se añade a la lista 'cat'.
Esta lista una vez se pasa esta bien definida y se agregan correctamente las categorías (si la imprimo por pantalla se muestra la lista correcta)
 
Es que nada tiene que ver eso.

Como te digo no se sacan todas las consultas de golpe.

Ahora saca un articulo.
Dentro de X minutos saca otro articulo y no puede ser de la misma categoria que el primero.
Dentro de X minutos saca otro articulo y no puede ser de la misma categoria que los dos primeros.

Y no se puede sacar y dejar almacenado por que puede haber por el medio modificaciones y que un articulo deje de estar disponible en el tiempo desde que se saca la primera consulta hasta que se va a entregar el ultimo.
entonces haz una subquery a la query que te pase donde quitas el ID de los artículos que se publicaron recientemente y no quieres incluir. Lo que quieres se puede hacer en una simple consulta para no estresar la BD(lo lamento siempre pienso en optimización tengo bases de datos con millones de registros y siempre la optimización por delante)

O puedes utilizar cache o redis para almacenar temporalmente esa lista de artículos que varían.
 
Cada vez que se extrae un articulo y se publica (en otra función), una vez publicado se añade a la lista 'cat'.
Esta lista una vez se pasa esta bien definida y se agregan correctamente las categorías (si la imprimo por pantalla se muestra la lista correcta)
Si tu error está en la variable cat no estas mostrando cómo la obtienes, solo mencionas que guardas la categoría.. pero como? Si sale duplicado es por algo
 
Si tu error está en la variable cat no estas mostrando cómo la obtienes, solo mencionas que guardas la categoría.. pero como?
La variable se define:

cat = []
Una vez que se publica, se agrega la categoria del item publicado a la lista
cat.append(record[4])

Con esta lista, si yo hago un print en la funcion que muestro arriba se muestra de la siguiente forma, esto en la segunda interacción por ejemplo, pero si dejo que continue se terminan repitiendo por que el query saca valores que no corresponden.

['Casa', 'Comida']


Aclaro que el query lo pego en mysql y funciona perfecto sin error, pero aqui, no se si es por alguna variable o por que, no devuelve los valores correctos.
 
entonces haz una subquery a la query que te pase donde quitas el ID de los artículos que se publicaron recientemente y no quieres incluir. Lo que quieres se puede hacer en una simple consulta para no estresar la BD(lo lamento siempre pienso en optimización tengo bases de datos con millones de registros y siempre la optimización por delante)

O puedes utilizar cache o redis para almacenar temporalmente esa lista de artículos que varían.
Eso seria lo más fácil.

Y tienes toda la razón, yo tampoco uso bases de datos tan pequeñas, lo normal, mas cómodo y que solucionaría problemas seria las categorías aparte.

Pero ya es cuestión, de por que no funciona, cuando la consulta sola si se ejecuta sin problemas mientras que al enviarla desde el script no... No tendria problemas en concatenar querys, inner join.... Pero ya es cuestión, de por que, este codigo de esta manera no funciona, cuando debería hacerlo.

Al final son como unos 200 registros que se borraran de un dia para otro pero que tienen muchas consultas, de ahí querer hacer las menores consultas posibles y ahorrar lo máximo (si es que doy como)
 
Me autocontesto por si a alguien le ha pasado, es problema del formato en que pasa la lista python a mysql.
Solución:

Python:
query = "SELECT * FROM ****** WHERE date = %s AND ****** NOT IN ({}) ".format(','.join(['%s'] * len(cat)))
params = [date.today()] + cat

con el format en la consulta y pasando la lista con {} en vez de %s solucionado.
 
Atrás
Arriba