【问题标题】:How can I update a specific cell in a sqlite database through python如何通过python更新sqlite数据库中的特定单元格
【发布时间】:2021-05-23 03:16:28
【问题描述】:

我有一个充满数字但作为字符串的数据库。我的主要目标是在 SQLite 数据库中获取一个单元格,将其转换为浮点数,然后用它更新单元格。但是我不明白如何更新 SQLite 数据库中的特定单元格。这是我的代码。

for row in cur:
    for col in row:
        try:
            fcol = float(col)
            cur.execute('UPDATE test SET ')
        except:
            print("FAIL")
            print(col)
            continue
        print("Replaced",col)
    print("Row done")
print("Completed")

基本上我的问题是如何更新 SQLite 数据库的特定单元格。

【问题讨论】:

  • col 列的类型是什么,正如您在 CREATE TABLE 语句中声明的那样?
  • 整个数据集都是数字,但是它们是字符串
  • 它很长,但这里有一个示例。它只是继续这样。创建表“测试”(“行”整数,“1”文本,“2”文本,“3”文本,“4”文本,“5”文本,“6”文本,“7”文本,“8”文本, “9” 文本, “10” 文本, “11” 文本, “12” 文本, “13” 文本, “14” 文本, “15” 文本, “16” 文本, “17” 文本, “18” 文本, "19" 文本, "20" 文本, "21" 文本, "22" 文本, };
  • 什么是“细胞”?数据库有表。表有列。您是在问如何更新特定行中的特定列?

标签: python sql sqlite


【解决方案1】:

问题是列被定义为TEXT,因此在获取时值总是字符串。有几种方法可以解决这个问题。

首先,您可以在从数据库中检索它们后将它们转换为floatDecimal。这既不方便又容易出错。

更好的方法可能是创建一个新列,类型为REAL,并使用旧列中的数据加载它。此示例创建并填充一个表,然后演示如何添加一个新列。

import random
import sqlite3


with sqlite3.connect('test.db') as conn:
    cur = conn.cursor()
    cur.execute('DROP TABLE IF EXISTS test')
    cur.execute('CREATE TABLE test (id INTEGER, col TEXT)')
    cur.executemany('INSERT INTO test (id, col) VALUES (?, ?)',
                    [(i, random.random(),) for i in range(3)])
    conn.commit()
    cur.execute('SELECT col FROM test')
    for row in cur:
        print(row)
    print()
    cur.execute('ALTER TABLE test ADD COLUMN new_col REAL')
    cur.execute('UPDATE test SET new_col = CAST(col AS REAL)')
    conn.commit()
    try:
        # Not all versions of Sqlite support DROP COLUMN
        cur.execute('ALTER TABLE test DROP COLUMN col')
        conn.commit()
    except sqlite3.OperationalError:
        conn.rollback()
    cur.execute('SELECT id, new_col FROM test')
    for row in cur:
        print(row)
    print()

第三,您可以创建一个具有正确数据类型的新表并从原始表中复制数据。和之前一样,这个示例创建并填充了一个表,然后演示了如何复制到一个新表。

with sqlite3.connect('test.db') as conn:
    cur = conn.cursor()
    cur.execute('DROP TABLE IF EXISTS test')
    cur.execute('CREATE TABLE test (id INTEGER, col TEXT)')
    cur.executemany('INSERT INTO test (id, col) VALUES (?, ?)', 
                    [(i, random.random(),) for i in range(3)])
    conn.commit()
    cur.execute('SELECT col FROM test')
    for row in cur:
        print(row)
    print()
    cur.execute('DROP TABLE IF EXISTS test2')
    cur.execute('CREATE TABLE test2 (id INTEGER, col REAL)')
    # The order of SELECTed columns must match the target columns.
    cur.execute("""INSERT INTO test2 (id, col)
                   SELECT t1.id, CAST(t1.col AS REAL) 
                   FROM test t1 
                   WHERE true""")
    conn.commit()
    cur.execute('SELECT id, col FROM test2')
    for row in cur:
        print(row)
    print()

一旦您对结果感到满意,您就可以删除原始表,甚至可以根据需要重命名新表。

在示例中,我每次都删除并重新创建原始表 - 您不想对您的表执行此操作!示例使用简单的两列表,但逻辑可以扩展为处理多列。

【讨论】:

  • 我查看了您的编码解决方案,并尝试了它们。但是,我的数据库非常大。而且真的很大,以至于我找不到为最终结果制作新表的方法。这就是为什么我把你的第一个放在我只是把表格中的每个单元格然后将它转换为浮点数的地方。到目前为止,我唯一需要做的就是将每个单元格更新为浮动版本。这就是我不知道该怎么做的事情,因为所有在线文章都只讨论如何更新行或列,而不是特定单元格。
  • 您可以使用 UPDATE tbl SET col = ? WHERE id = ? 更新单个单元格 - WHERE 子句允许您指定更新哪些单元格。但是您不能更改单元格中数据的基础 type - 如果列类型是 TEXT,那么它包含的值将是文本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-29
  • 2021-03-27
  • 2020-08-11
  • 1970-01-01
  • 2013-01-19
  • 1970-01-01
相关资源
最近更新 更多