【问题标题】:Get data from database and write it back in again从数据库中获取数据并重新写入
【发布时间】:2022-01-07 02:59:25
【问题描述】:

我通过读取一个 excel 文件并将其写入数据库来编写一个函数。这行得通!

从数据库中获取数据也可以。

我卡住的地方是函数应该读取每一行,计算它并将结果写回数据库。

我还想知道在数据库中写入了多少行,然后将该数字传递给 for 循环。

第一个函数用于读取Excel数据并将其写入数据库:

    def Load_into_database():
    file_path = label_file["text"]
    try:
        excel_filename = r"{}".format(file_path)
        if excel_filename[-4:] == ".csv":
            df = pd.read_csv(excel_filename, header=0, names=['Probe_Dehnung', 'Probe_Standardkraft'], sheet_name='Probe 1', skiprows=2, usecols="A:B")
        else:
            df = pd.read_excel(excel_filename, header=0, names=['Probe_Dehnung', 'Probe_Standardkraft'], sheet_name='Probe 1', skiprows=2, usecols="A:B")

    except ValueError:
        tk.messagebox.showerror("Information", "The file you have chosen is invalid")
        return None
    except FileNotFoundError:
        tk.messagebox.showerror("Information", f"No such file as {file_path}")
        return None

    engine = create_engine("mariadb+mariadbconnector://root:pw123@127.0.0.1:3306/polymer")
    df.to_sql('zugversuch_probe_1',
              con=engine,
              if_exists='append',
              index=False)

    c.execute("SELECT * FROM zugversuch_probe_1")
    records = c.fetchall()
    print("Records", records)
    calculation(records)

第二个函数是从一列中读取每一行,逐行计算,然后写回数据库:

def calculation(records):
    # query the database
    for record_id in records:
        c.execute("SELECT * FROM zugversuch_probe_1 WHERE ID = " + str(record_id))
        records = c.fetchall()[0]

        # Berechnung Dehnung
        dehnung = calc_dehnung(records[1])
        print("Dehnung", dehnung)

        sql_command = """
        INSERT INTO zugversuch_probe_1
        (Dehnung)
        VALUES(%s)"""

        c.execute("""UPDATE zugversuch_probe_1 SET
            Dehnung = %s
            WHERE ID = %s""",
                  (
                      dehnung.get(),
                      record_id
                  ))

        values = (dehnung.get())

        # commit changes
        conn.commit
        # close connection
        conn.close()

def calc_dehnung(value_list):
    return (value_list[0] / 0.123) * 100

运行代码后,我收到错误消息:

c.execute("SELECT * FROM zugversuch_probe_1 WHERE ID = " + str(record_id)) mariadb.OperationalError:“where 子句”中的未知列“None”

很遗憾,我也有删除数据后数据库中的ID没有从0重新开始,而是继续计数的问题。

这是数据库的截图: Screenshot Database

这是 Excel 文件的屏幕截图: Screenshot Excel

提前谢谢你

【问题讨论】:

  • 你的sql语句容易受到SQL注入owasp.org/www-community/attacks/SQL_Injection
  • 是的,但这不是他的问题。此外,只有在处理用户输入时,sql 注入才有意义。我在这里看不到任何用户输入,这似乎是一个离线脚本。可以提一下,但这不是导致他错误的原因。

标签: python sql database mariadb


【解决方案1】:

c.fetchall() 返回您需要在循环中解包的元组列表

c.execute("SELECT * FROM zugversuch_probe_1")
for record in c.fetchall():
    record_id, probe_dehnung, dehnung, probe_standardkraft = record
    dehnung = calc_dehnung(probe_dehnung)
    c.execute("""UPDATE zugversuch_probe_1 SET
        Dehnung = %s
        WHERE ID = %s""",
              (
                  dehnung,
                  record_id
              ))

【讨论】:

  • 谢谢。我尝试了您的建议,但也收到错误消息:“return (value_list[0] / 0.123) * 100 TypeError: 'float' object is not subscriptable” 我将行 dehnung = calc_dehnung(probe_dehnung) 更改为 dehnung = (probe_dehnung[0] / 0.123) * 100 现在得到错误消息:dehnung.get(), AttributeError: 'float' object has no attribute 'get' 我该怎么做才能修复错误?
  • 抱歉 .get 是您的代码遗留下来的,我已将其删除
  • 我没有收到错误消息,但数据库中的“Dehnung”列仍然为空。
【解决方案2】:

我看不出您使用 dehnung.get() 的任何原因。当您从字典中检索值时会使用 .get() 函数,但 dehnung 似乎是一个列表(或数字?)。这可能会以某种意想不到的方式破坏您的代码并混淆 sql 引擎。

您在此处打印该变量

print("Dehnung", dehnung)

如果这是您要插入的值,只需在接下来的 2 次使用时删除 .get()。

您还需要解压缩变量“record_id”中的值。我建议您将此变量重命名为“record”,因为它不是 record_id - 它是来自 db 的结果的一行,其中包含该行中的所有值,而 id 只是其中一个(第一个)。您可以使用 record_id[0]

访问它
c.execute("SELECT * FROM zugversuch_probe_1 WHERE ID = " + str(record_id[0]))

您也可能在这里使用了错误的值:

dehnung = calc_dehnung(records[1])

您可能打算使用record_id[1] 而不是records[1]。同样,我强烈建议您将变量“record_id”重命名为“record”,这似乎是一些混乱的根源

【讨论】:

  • 好的,谢谢。我现在已将“record_id”更改为“record”,如您所描述的两行: c.execute("SELECT * FROM zugversuch_probe_1 WHERE ID = " + str(record[0])) dehnung = calc_dehnung(record[1])我现在收到错误:return (value_list[0] / 0.123) * 100 TypeError: 'float' object is not subscriptable
  • 您必须将记录[1] 重命名为记录[1] 删除函数calc_dehnung() 中的[0]。我还建议将变量“value_list”重命名为“value”,因为现在您不再向该函数发送列表,而只是发送数字(或浮点数)本身。您遇到的问题是意识到 sql 返回列表列表(记录)。其中一行是一个列表(记录),该列表的一个值是您要转换的浮点数。您应该尝试通过打印和使用适当的变量名称来跟踪这一点。
  • 好的,谢谢,我试过了,但现在我收到错误消息:c.execute("""UPDATE zugversuch_probe_1 SET mariadb.DataError: Data type 'tuple' in column 1 not supported in MariaDB Connector/Python
  • 这是新代码:def calculation(records): for record in records: c.execute("SELECT * FROM zugversuch_probe_1 WHERE ID = " + str(record[0])) records = c.fetchall()[0] dehnung = calc_dehnung(record[1]) print("Dehnung", dehnung) sql_command = """INSERT INTO zugversuch_probe_1 (Dehnung) VALUES(%s)""" c.execute("""UPDATE zugversuch_probe_1 SET Dehnung = %s WHERE ID = %s""", (dehnung, record)) values = (dehnung) conn.commit conn.close()
【解决方案3】:

是的,它有效!

因为我忘记了conn.commit()中的括号,所以它不起作用

这是我从@vinzBad 获得的新代码

    def update():
        c.execute("SELECT * FROM zugversuch_probe_1")
        for record in c.fetchall():
            try:
                record_id, probe_dehnung, dehnung, probe_standardkraft = record
                dehnung = (probe_dehnung / 0.123) * 100

                c.execute("""UPDATE zugversuch_probe_1 SET
                        Dehnung = %s
                        WHERE ID = %s""",
                          (
                              dehnung,
                              record_id
                          ))

                conn.commit()

            except mariadb.Error as e:
                print(f"Error connecting to MariaDB Platform: {e}")
                sys.exit(1)

        conn.close()

这是截图mariadb

感谢您的帮助!

【讨论】:

  • 很高兴你能解决它。请对帮助您找到解决方案的答案进行投票,您也可以接受您的答案以关闭此问题
猜你喜欢
  • 2014-07-25
  • 1970-01-01
  • 1970-01-01
  • 2017-05-16
  • 2012-08-10
  • 1970-01-01
  • 2013-10-10
  • 1970-01-01
  • 2022-01-07
相关资源
最近更新 更多