CSV 中列的灵活顺序与应用程序中项目的硬编码显示

Flexible order of columns in CSV with hard coded display of items in an app

简而言之

我有一个 CSV,其列的顺序和名称可以经常更改。我正在构建一个应将此 csv 加载到 sqlite3 数据库中的应用程序,检索特定行并将其显示在相应的小部件中:Label_Name, TextInput_Address, Button_Date...

每个小部件接收的信息都是硬编码的,直到现在都是基于 return 由 sqlite3 编辑的元组索引,它反映了 sqlite3 中列的顺序这反映了 CSV 的顺序。

我如何才能一方面灵活地组织我的 CSV 列,另一方面又对我的小部件进行固定的硬编码组织?

OLD CSV
"ID","Year", "Name", "Address", "Group", "Answers"

NEW CSV
"ID","Group", "Name", "Address", "Year_joined", "Answers"

注意顺序改变了 "Group" 变成了 "Group" 而 "Year" 变成了 "Year_joined"

我的代码的一些相关部分:

#reading CSV and storing in db
with open(csvfile, encoding='utf-8') as f:
    reader = csv.reader(f)
    header= True
    for row in reader:
        if header:
            header= False
            query = "CREATE TABLE {0} ({1})"
            sql= query.format("MyCSV",','.join(["{} text1".format(column) for column in row]))
            c.execute(sql)
            insertsql = query.format(tablename,
                        ", ".join([ "?" for column in row ])))
        else:
            c.execute(insertsql, row)
conn.commit()

...

#getting the row I want to display
c.execute("SELECT * FROM {} WHERE id={}".format("MyCSV", 1))
row_for_db = c.fetchall()[0]

...

#dispatching the data from the row into each widget (based on column order)
Label_ID=tag[0]
Button_Date=tag[1]
Txt_Input_message=tag[2]

详情

我正在构建一个应显示 CSV 文件中条目的所有数据的应用程序(最多 1000 多行,28 列)。应用程序中有 28 个小部件,每个小部件都应显示条目中的相应数据:Label_Name、TextInput_Address、Button_Date...在应用程序中,CSV 存储在一个 Sqlite3 中分贝。

如果 CSV 中列的 order/name(以及 sqlite 数据库)被修复,我只需要执行 sql 来检索行我想显示然后使用 sqlite 的元组 return 的索引将每个数据分派到其相应的小部件中。 但是,CSV 列的顺序和名称会发生​​变化(有时非常频繁)。那么,我怎样才能一方面拥有 CSV 列的灵活组织,另一方面又拥有固定的、硬编码的小部件组织。

我想过使用第二个 CSV 来跟踪列的当前名称和索引与在应用程序中硬编码的列的名称和索引的对应关系。

但这很麻烦,第二个 CSV 必须手动编辑,这意味着至少有一些人为错误。

有没有更好的方法来做我想做的事?

考虑使用 sqlite 的命令行 .import facility called by Python's subProcess,它可以直接从 csv 文件创建 tables,因此将读入 any headers 作为只要它在进程中创建 table 并且不附加到现有的。下面将三个命令合二为一 shell:

from subprocess import Popen, PIPE, STDOUT

cmd1 = 'sqlite3 "/path/to/database.db"'
cmd2 = 'sqlite3 .mode csv'
cmd3 = 'sqlite3 .import "/path/to/file.csv" mytable'

p = Popen("{}; {}; {}".format(cmd1, cmd2, cmd3), shell=True, stdin=PIPE, 
          stdout=PIPE, stderr=STDOUT, close_fds=True)

output, error = p.communicate()  

if p.returncode == 0:            
  print('OUTPUT:\n {0}'.format(output.decode("utf-8")))            
else:                
  print('ERROR:\n {0}'.format(error.decode("utf-8")))