处理日期时间字符串时如何更新 SQLite3 中的属性行

How to update rows of an attribute in SQLite3 when dealing with date-time string

我正在尝试对天气预报数据库进行修补。我需要像这样手动更改日期列的每一行: by changing the date format to this new format: .

请记住,此 table 及其属性是在没有任何条件的情况下创建的。因此,int/str/bools/any 也可能在这些行中的任何一行中,它应该有效。

这个新格式是由这个脚本执行的,一个 for 循环,它简单地提取旧数据库值和 returns 个包含格式化字符串的变量。

connection = sqlite3.connect('\.db\')
cursor = connection.cursor()
ROWID = cursor.execute('SELECT ROWID FROM update_test').fetchall()
Date = cursor.execute('SELECT Date FROM update_test').fetchall()


for row, dates in zip(ROWID, Date):  # tuple
    for i, x in zip(row, dates):  # strings
        try:
            weekdays = r'^...'
            regex = r'...-[\d\d]{1,}-Jan'
            new_year = re.findall(regex, x)
            for match in new_year:
                updated_dates = f'{"2022"}{re.sub(weekdays, "", match)}'
                date_object = datetime.datetime.strptime(updated_dates, '%Y-%d-%b').strftime('%Y-%m-%d')
                print(i, date_object)
                # update('test.db', 'update_test', 'date', date_object, i) # I want this bit to work
        except TypeError:
            pass

现在,我通常会将这些变量传递到 INSERT 函数中,例如:

def update(url, table, setVar, setVal, setID):
    try:
        connection = sqlite3.connect(url)
        cursor = connection.cursor()
        try:
            cursor.execute(f'UPDATE {table} SET {setVar} = {setVal} WHERE ROWID = {setID}')
            connection.commit()
        except sqlite3.Error as error:
            print(f'Error: \n {error}')
            ...
            cursor.execute("SELECT name "
                           "FROM sqlite_master "
                           "WHERE type='table'")
            ... logging
            ... logging
            ... logging
        ... logging
        ... logging
        connection.close()
        ... logging
    except pandas.io.sql.DatabaseError:
        ...logging

但是一件非常奇怪的事情发生了,它只会像这样更新格式化字符串的年份:

此外,通常,当在 for 循环中使用时,今年会递增 -= 1 年。所以:2019、2018、2017 ...对于更新函数中指定的每一行。

我理想的输出是日期将更改为我在该 for 循环(第一个脚本预览)中初始化的新格式,并且只有那些指定的行(无论如何已经有效)。

update('test.db', 'update_test', 'date', date_object, i) # I want this bit to work

问题是您正在对 SQL 进行自己的替换。你最终会得到:

UPDATE table SET setVar = 2022-03-01 WHERE ROWID = xxx

Sqlite 将其视为算术表达式。 2022减3减1就是2018.

短期修复是引用值:

cursor.execute(f'UPDATE {table} SET {setVar} = "{setVal}" WHERE ROWID = {setID}')

更好的解决方法是让连接器进行替换:

cursor.execute(f'UPDATE {table} SET {setVar} = ? WHERE ROWID = ?', (setVal, setID))

跟进

附带说明一下,您的正则表达式在这里完全没有必要。

connection = sqlite3.connect('\.db\')
cursor = connection.cursor()
rowset = cursor.execute('SELECT ROWID,Date FROM update_test')

for rowid,date in rowset:
    parts = date.split('-')
    if parts[2] == 'Jan':
        parts[0] = '2022'
        updated_dates = '-'.join(parts)
        date_object = datetime.datetime.strptime(updated_dates, '%Y-%d-%b').strftime('%Y-%m-%d')
        print(rowid, date_object)