【问题标题】:Python put Database records in NamedtuplePython将数据库记录放在Namedtuple中
【发布时间】:2013-11-20 13:10:35
【问题描述】:

我正在尝试在 python (2.7) 中编写一些代码:

  1. 在 sqlite 中打开数据库
  2. 查询数据库,得到一些结果。该数据库有多个表,我需要来自不同表的记录: 数据库是这样的:
    • data.db ---> [table1[col1, col2, col3], table2[col1, col2, col3]]
  3. 遍历结果
  4. 对结果做一些事情(例如在记录中有一个需要解码的日期)
  5. 将所有记录存储在一个命名元组中以供进一步访问

从现在开始,我已经完成了第 1、2、3 和 4 部分,但我不知道如何将结果存储在命名元组中。假设在每次迭代中,我将我需要的数据存储在 namedtuple 中的临时变量中:

for result in results:
var1 = table1.col1
var2 = table2.col1
var3 = table3.col1

(现在我想对变量做点什么,但这不是问题,并将 3 个变量存储在一个命名元组中)

contacts = namedtuple('contacts', 'Z_PK ZFULLNAME ZPHONE ZTEXT ZDATE')

    if has_contacts_sqlite:

        # reading contacts from database
        # 1st step: ZWAPHONE table
        query = "SELECT * FROM ZWAPHONE"
        self.tempcur.execute(query)
        tempcontacts = self.tempcur.fetchall()

        for contact in tempcontacts:
            id = contact.Z_PK
            contact_key = contact.ZCONTACT
            favorite_key = contact.ZFAVORITE
            status_key = contact.ZSTATUS
            phonenum = contact.ZPHONE

            # 2nd step: name from ZWACONTACT table
            query = "SELECT * FROM ZWACONTACT WHERE Z_PK=?;"
            self.tempcur.execute(query, [contact_key])
            contact_entry = self.tempcur.fetchone()
            if contact_entry == None:
                name = "N/A"
            else:
                name = contact_entry.ZFULLNAME

            # 3rd step: status from ZWASTATUS table
            query = "SELECT * FROM ZWASTATUS WHERE Z_PK=?;"
            self.tempcur.execute(query, [status_key])
            status_entry = self.tempcur.fetchone()
            if status_entry == None:
                text = "N/A"
                date = "N/A"
            else:
                text = status_entry.ZTEXT
                date = self.formatDate(status_entry.ZDATE)

            #print ("%s" %(id))
            #print ("%s" %(name.encode(sys.stdout.encoding, errors='replace')))
            #print ("%s" %(phonenum.encode(sys.stdout.encoding, errors='replace')))
            #print ("%s" %(text.encode(sys.stdout.encoding, errors='replace')))
            #print ("%s" %(date))

            contact = contacts(id, name, phonenum, text, date)


print contacts
for line in contacts:
    print line

【问题讨论】:

    标签: python sql sqlite iteration namedtuple


    【解决方案1】:

    namedtuple() 只不过是使用工厂函数生成的类:

    SomeRowResult = namedtuple('SomeRowResult', 'var1 var2 var3')
    

    这里SomeRowResult是一个类对象(tuple的子类),调用它会创建类的实例:

    for result in results:
        result = SomeRowResult(table1.col1, table2.col1, table3.col1)
    

    如果您想获得这些结果的列表,则需要显式构建该列表:

    all_results = []
    for result in results:
        result = SomeRowResult(table1.col1, table2.col1, table3.col1)
        all_results.append(result)
    

    【讨论】:

    • 感谢您的回复。我添加了我的代码。有语法错误吗?因为它还没有运行。为了测试,我试图遍历“联系人”并打印结果,但它说:TypeError:'type' object is not iterable。
    • @user3013106:您发布的代码应该可以正常工作;您确定您没有在代码中的任何位置为 contacts 分配任何其他内容吗?
    • @user3013106:另外,TypeObject 看起来与namedtuple 完全无关。什么是追溯?究竟是哪一行代码引发了该错误?
    • 不。我正在使用此代码进行测试: print contacts return: 和 for line in contacts: print line 并且它返回不可迭代(对不起,我无法确定在 cmets 中格式化代码一个可读的形式)
    • @Rigel:是的,你可以遍历all_results;每个项目都是一个 namedtuple 实例,具有您定义的所有属性。但是,您不能循环创建实例的类。这就像尝试循环遍历 dicttuple 以获取程序中创建的所有字典或元组。 Python 不是那样工作的。
    猜你喜欢
    • 2018-11-10
    • 2011-01-19
    • 1970-01-01
    • 2013-12-14
    • 1970-01-01
    • 1970-01-01
    • 2013-11-23
    • 2011-02-25
    • 2020-08-13
    相关资源
    最近更新 更多