import sqlite3

def find_details(id2find):
    db = sqlite3.connect("surfersDB.sdb")
    
    # grap surfer data from database
    db.row_factory = sqlite3.Row
    cursor = db.cursor()
    cursor.execute("select * from surfers")
    rows = cursor.fetchall()

In the code snippet above from "Head First Programming", the syntax for the database code is poorly explained.

Is row_factory a call, method, or just a variable based on sqlite3.Row. And what is sqlite3.Row?

And if row_factory is just a variable, why is it proceeded with a db and the two cursor lines and the rows in the line rows = cursor.getchall are not.

Non of this is explained in the book, please help.

Recommended Answers

All 4 Replies

Use Python docs ( http://docs.python.org/library/sqlite3.html or for example IDLE F1):

Connection.row_factory
You can change this attribute to a callable that accepts the cursor and the original row as a tuple and will return the real result row. This way, you can implement more advanced ways of returning results, such as returning an object that can also access columns by name.

Example:

import sqlite3

def dict_factory(cursor, row):
    d = {}
    for idx, col in enumerate(cursor.description):
        d[col[0]] = row[idx]
    return d

con = sqlite3.connect(":memory:")
con.row_factory = dict_factory
cur = con.cursor()
cur.execute("select 1 as a")
print cur.fetchone()["a"]

If returning a tuple doesn’t suffice and you want name-based access to columns, you should consider setting row_factory to the highly-optimized sqlite3.Row type. Row provides both index-based and case-insensitive name-based access to columns with almost no memory overhead. It will probably be better than your own custom dictionary-based approach or even a db_row based solution.

12.13.4. Row Objects
class sqlite3.Row
A Row instance serves as a highly optimized row_factory for Connection objects. It tries to mimic a tuple in most of its features.

It supports mapping access by column name and index, iteration, representation, equality testing and len().

If two Row objects have exactly the same columns and their members are equal, they compare equal.

Changed in version 2.6: Added iteration and equality (hashability)

From the PySQLite docs, a rather dated example; it allows case insensitive column access by name:

Highly optimized row_factory for column access by name
======================================================

A new function has been implemented that allows for case-insensitive
column access by name with minimal performance and memory impact,
unlike a dictionary or db_row-based approach.

To enable it, set the row_factory attribute of your connection to
sqlite.Row:

from pysqlite2 import dbapi2 as sqlite
    con = sqlite.connect(...)
    con.row_factory = sqlite.Row
    cur = con.cursor()
    cur.execute("select name_last, age from people")
    for row in cur:
        print row["Name_Last"], row[1]
import sqlite3

def find_details(id2find):
    db = sqlite3.connect("surfersDB.sdb")
    
    # grap surfer data from database
    db.row_factory = sqlite3.Row
    cursor = db.cursor()
    cursor.execute("select * from surfers")
    rows = cursor.fetchall()

In the code snippet above from "Head First Programming", the syntax for the database code is poorly explained.

Is row_factory a call, method, or just a variable based on sqlite3.Row. And what is sqlite3.Row?

And if row_factory is just a variable, why is it proceeded with a db and the two cursor lines and the rows in the line rows = cursor.getchall are not.

Non of this is explained in the book, please help.

Are you actually using the book, or are you just looking at the online example code?

I have to say the code could stand a few more comments ...

# example and db file from book "Head First Programming"
# http://www.headfirstlabs.com/books/hfprog/

import sqlite3 

def find_details(id2find): 
    db = sqlite3.connect("surfersDB.sdb")
    # assigns names/keys that are part of the database db
    # like 'id', 'name', 'country', ... 
    db.row_factory = sqlite3.Row
    #print(db.row_factory)  # <class 'sqlite3.Row'> 
    cursor = db.cursor() 
    cursor.execute("select * from surfers") 
    rows = cursor.fetchall()
    for row in rows: 
        if row['id'] == id2find: 
            s = {} 
            s['id']      = str(row['id']) 
            s['name']    = row['name'] 
            s['country'] = row['country'] 
            s['average'] = str(row['average']) 
            s['board']   = row['board'] 
            s['age']     = str(row['age']) 
            cursor.close()
            # return a dictionary of this surfer 
            return(s) 
    cursor.close()
    # return an empty dictionary if id not found 
    return({})

# id in this case is an integer from 101 to 107
#lookup_id = int(input("Enter the id of the surfer: "))
lookup_id = 107 
surfer = find_details(lookup_id) 
if surfer: 
    print("ID:         " + surfer['id']) 
    print("Name:       " + surfer['name']) 
    print("Country:    " + surfer['country']) 
    print("Average:    " + surfer['average']) 
    print("Board type: " + surfer['board']) 
    print("Age:        " + surfer['age'])

"""my result -->
ID:         107
Name:       Aaron Valentino
Country:    Italy
Average:    8.98
Board type: Gun
Age:        19
"""

Note:
This book teaches you various aspects of computer programming, and is not meant to be a book on the details of the Python language.

Thanks all.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.