Necesito consultar repetidamente una base de datos MySQL desde Python, ya que los datos están cambiando rápidamente. Cada vez que se leen los datos, se transfieren a una lista.

Supuse que simplemente poner la consulta en un bucle obtendría los datos de la base de datos en cada iteración. Parece que no.

import mysql.connector
from mysql.connector import Error
from time import sleep

# Create empty list to store values from database.
listSize = 100
myList = []

for i in range(listSize):
    myList.append([[0,0,0]])

# Connect to MySQL Server
mydb = mysql.connector.connect(host='localhost',
                               database='db',
                               user='user',
                               password='pass')

# Main loop
while True:

    # SQL query
    sql = "SELECT * FROM table"

    # Read the database, store as a dictionary
    mycursor = mydb.cursor(dictionary=True)
    mycursor.execute(sql)

    # Store data in rows
    myresult = mycursor.fetchall()

    # Transfer data into list
    for row in myresult:
        myList[int(row["rowID"])] = (row["a"], row["b"], row["c"])

        print(myList[int(row["rowID"])])

    print("---")
    sleep (0.1)

He intentado usar fetchall, fetchmany y fetchone.

1
wibbleface 11 abr. 2020 a las 18:15

2 respuestas

La mejor respuesta

Debe confirmar la conexión después de cada consulta. Esto confirma la transacción actual y asegura que la próxima transacción (implícita) recogerá los cambios realizados mientras la transacción anterior estaba activa.

# Main loop
while True:

    # SQL query
    sql = "SELECT * FROM table"

    # Read the database, store as a dictionary
    mycursor = mydb.cursor(dictionary=True)
    mycursor.execute(sql)

    # Store data in rows
    myresult = mycursor.fetchall()

    # Transfer data into list
    for row in myresult:
        myList[int(row["rowID"])] = (row["a"], row["b"], row["c"])

        print(myList[int(row["rowID"])])

    # Commit !
    mydb.commit()
    print("---")
    sleep (0.1)

El concepto aquí es niveles de aislamiento. Del documentos (énfasis mío ):

LECTURA REPETIBLE

Este es el nivel de aislamiento predeterminado para InnoDB. Lecturas consistentes dentro de la misma transacción lee la instantánea establecida por la primera lectura .

1
snakecharmerb 11 abr. 2020 a las 17:53

Haría algunos cambios. Primero, declare el cursor antes del bucle while. También haría un cursor tamponado. Y finalmente, cierre el cursor y la base de datos después de que el archivo esté listo. Espero que esto ayude.

import mysql.connector
from mysql.connector import Error
from time import sleep

# Create empty list to store values from database.
listSize = 100
myList = []

for i in range(listSize):
    myList.append([[0,0,0]])

# Connect to MySQL Server
mydb = mysql.connector.connect(host='localhost',
                               database='db',
                               user='user',
                               password='pass')
mycursor = mydb.cursor(buffered=True, dictionary=True)

# Main loop
while True:

    # SQL query
    sql = "SELECT * FROM table"

    # Read the database, store as a dictionary
    mycursor.execute(sql)

    # Store data in rows
    myresult = mycursor.fetchall()

    # Transfer data into list
    for row in myresult:
        myList[int(row["rowID"])] = (row["a"], row["b"], row["c"])

        print(myList[int(row["rowID"])])

    print("---")
    sleep (0.1)
mycursor.close()
mydb.close()
1
R Lynch 11 abr. 2020 a las 15:20