Mapping result rows to namedtuple in python sqlite

前端 未结 3 1133
说谎
说谎 2020-12-31 06:42

I am playing a bit with the python api for sqlite3, i have a little table for store languages with an id, name and creation_date fields. I am trying to map the raw query res

相关标签:
3条回答
  • 2020-12-31 06:54

    There is a much easier way! Sqlite3 provides a way for the user to define "row factories". These row factories take the cursor and the tuple row and can return whatever type of object it wants.

    Once you set the row factory with

    con.row_factory = my_row_factory
    

    then rows returned by the cursor will be the result of my_row_factory applied to the tuple-row. For example,

    import sqlite3
    import collections
    
    LanguageRecord = collections.namedtuple('LanguageRecord', 'id name creation_date')
    def namedtuple_factory(cursor, row):
        return LanguageRecord(*row)
    
    con = sqlite3.connect(":memory:")
    con.row_factory = namedtuple_factory
    cur = con.cursor()
    cur.execute("select 1,2,3")
    print(cur.fetchone())
    

    yields

    LanguageRecord(id=1, name=2, creation_date=3)
    

    For another example of how to define a namedtuple factory, see this post.


    By the way, if you set

    conn.row_factory = sqlite3.Row
    

    then rows are returned as dicts, whose keys are the table's column names. Thus, instead of accessing parts of the namedtuple with things like row.creation_date you could just use the builtin sqlite3.Row row factory and access the equivalent with row['creation_date'].

    0 讨论(0)
  • 2020-12-31 06:55

    I think better to use for language in map(LanguageRecord._make, c.fetchall()[:1]): Because it can cause IndexError with fetchall()[0].

    If you need one result and there is already "WHERE" in query. As I understand query should return one row. Early optimization is evil. :)

    0 讨论(0)
  • 2020-12-31 07:14

    An improved row_factory is actually this, which can be reused for all sorts of queries:

    from collections import namedtuple
    
    def namedtuple_factory(cursor, row):
        """Returns sqlite rows as named tuples."""
        fields = [col[0] for col in cursor.description]
        Row = namedtuple("Row", fields)
        return Row(*row)
    
    conn = sqlite3.connect(":memory:")
    conn.row_factory = namedtuple_factory
    cur = con.cursor()
    
    0 讨论(0)
提交回复
热议问题