ZetCode

Python sqlite3.Row.__len__ Method

Last modified April 15, 2025

This comprehensive guide explores Python's sqlite3.Row.__len__ method, which returns the number of columns in a row. We'll cover basic usage, practical examples, and common patterns.

Basic Definitions

The sqlite3.Row.__len__ method is a special method that returns the number of columns in a row object. It's called when using the built-in len function on a row.

Key characteristics: it's automatically available on sqlite3.Row objects, returns an integer count of columns, and is useful for dynamic column handling.

Basic Row Length Measurement

Here's the simplest usage of sqlite3.Row.__len__ to count columns in a query result.

basic_len.py
import sqlite3

with sqlite3.connect(':memory:') as conn:
    conn.row_factory = sqlite3.Row
    cursor = conn.cursor()
    
    cursor.execute('''CREATE TABLE test (id INTEGER, name TEXT, value REAL)''')
    cursor.execute("INSERT INTO test VALUES (1, 'Test', 3.14)")
    
    cursor.execute("SELECT * FROM test")
    row = cursor.fetchone()
    
    print(len(row))  # Output: 3

This example creates an in-memory database with a table of three columns. The len function calls __len__ internally to count columns.

The output shows 3, matching the number of columns in our table. This is the most basic use case for row length measurement.

Comparing Row Lengths

This example demonstrates comparing row lengths from different queries to ensure consistent column counts.

compare_len.py
import sqlite3

with sqlite3.connect('example.db') as conn:
    conn.row_factory = sqlite3.Row
    cursor = conn.cursor()
    
    # First query
    cursor.execute("SELECT * FROM users")
    full_row = cursor.fetchone()
    
    # Second query
    cursor.execute("SELECT name, age FROM users")
    partial_row = cursor.fetchone()
    
    print(f"Full row length: {len(full_row)}")      # Typically more columns
    print(f"Partial row length: {len(partial_row)}") # Fewer columns
    
    if len(full_row) != len(partial_row):
        print("Warning: Column counts differ between queries")

This code compares the length of rows from different SELECT statements. The first query gets all columns while the second selects specific columns.

The length comparison helps detect when queries return unexpected column counts, which is useful for data validation and debugging.

Dynamic Column Processing

Here we use __len__ to dynamically process rows without knowing the column count in advance.

dynamic_processing.py
import sqlite3

with sqlite3.connect('inventory.db') as conn:
    conn.row_factory = sqlite3.Row
    cursor = conn.cursor()
    
    cursor.execute("SELECT * FROM products")
    rows = cursor.fetchall()
    
    for row in rows:
        print(f"Product has {len(row)} attributes:")
        for i in range(len(row)):
            print(f"  Column {i}: {row[i]}")

This example processes each product row dynamically by first checking its length with len, then iterating through all columns.

Dynamic processing is useful when working with tables whose schema might change or when writing generic database utilities.

Validating Row Structure

This example uses __len__ to validate that rows match expected column counts before processing.

validation.py
import sqlite3

EXPECTED_COLUMNS = 4

with sqlite3.connect('sales.db') as conn:
    conn.row_factory = sqlite3.Row
    cursor = conn.cursor()
    
    cursor.execute("SELECT * FROM transactions")
    rows = cursor.fetchall()
    
    for row in rows:
        if len(row) != EXPECTED_COLUMNS:
            print(f"Warning: Row has {len(row)} columns, expected {EXPECTED_COLUMNS}")
            continue
            
        # Process valid rows
        print("Processing valid transaction:", dict(row))

The code checks each row's length against an expected value before processing. Rows with unexpected column counts are skipped with a warning.

This validation pattern helps catch schema changes or query errors that might affect data processing pipelines.

Row Length in Data Export

This example shows using __len__ when exporting data to CSV format, ensuring consistent column counts.

export_csv.py
import sqlite3
import csv

with sqlite3.connect('data.db') as conn:
    conn.row_factory = sqlite3.Row
    cursor = conn.cursor()
    
    cursor.execute("SELECT * FROM measurements")
    rows = cursor.fetchall()
    
    if not rows:
        print("No data to export")
    else:
        with open('measurements.csv', 'w', newline='') as f:
            writer = csv.writer(f)
            
            # Write header
            writer.writerow(rows[0].keys())
            
            # Write data
            for row in rows:
                if len(row) != len(rows[0]):
                    print(f"Skipping row with inconsistent columns: {len(row)}")
                    continue
                writer.writerow(list(row))

The export process first checks the column count of the first row, then verifies all subsequent rows match this count before writing to CSV.

This ensures the exported CSV file maintains consistent column structure throughout, preventing data corruption.

Row Length Statistics

This example collects statistics about row lengths in a table, useful for data analysis and quality checks.

statistics.py
import sqlite3
from collections import defaultdict

with sqlite3.connect('survey.db') as conn:
    conn.row_factory = sqlite3.Row
    cursor = conn.cursor()
    
    cursor.execute("SELECT * FROM responses")
    rows = cursor.fetchall()
    
    length_counts = defaultdict(int)
    for row in rows:
        length_counts[len(row)] += 1
    
    print("Row length distribution:")
    for length, count in sorted(length_counts.items()):
        print(f"{length} columns: {count} rows")
    
    if len(length_counts) > 1:
        print("Warning: Inconsistent column counts detected")

The code counts how many rows have each possible column length, then reports the distribution. Inconsistent lengths might indicate data quality issues.

This statistical approach helps identify tables with variable row structures, which could affect data processing applications.

Combining with Other Row Methods

This final example combines __len__ with other Row methods for comprehensive row analysis.

combined_methods.py
import sqlite3

with sqlite3.connect('library.db') as conn:
    conn.row_factory = sqlite3.Row
    cursor = conn.cursor()
    
    cursor.execute("SELECT * FROM books LIMIT 1")
    row = cursor.fetchone()
    
    if row:
        print(f"Book record has {len(row)} columns:")
        print(f"Column names: {row.keys()}")
        print(f"First column: {row[0]}")
        print(f"Title: {row['title']}")

After checking the row length with len, the example demonstrates accessing columns by index, name, and listing all column names.

This shows how __len__ fits into the broader Row API, providing complete information about result set structure.

Best Practices

Source References

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Python tutorials.