Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python dataclasses and sqlite3 adapters

What is the cleanest way to commit data stored in instances of a dataclass contained in a list to SQLite with sqlite3's executemany?

For example:

@dataclass
class Person:
    name: str
    age: int

a = Person("Alice", 21)
b = Person("Bob", 22)
c = Person("Charlie", 23)

people = [a, b, c] 

# ...

cursor.executemany(f"INSERT INTO {table} ({headers}) ({placeholders})", people) # <-- fails, obviously

Is there a built-in mechanism that does the work for me (goes over each attribute of the dataclass), or an idiomatic way, or, if not, how do I implement an adapter for this without explicitly listing the attributes one by one?

I could convert it to a list of tuples, that works out of the box, yet feels redundant.

like image 999
astrochicken Avatar asked Oct 31 '25 10:10

astrochicken


1 Answers

Use the astuple() function to convert the dataclass instances to tuples.

from dataclasses import dataclass, fields, astuple

field_names = [f.name for f in fields(Person)]
headers = ','.join(field_names)
people = map(astuple, [a, b, c])
placeholders = ','.join(['?'] * len(field_names))
table = 'persons'

cursor.executemany(f"INSERT INTO {table} ({headers}) ({placeholders})", people)
like image 153
Barmar Avatar answered Nov 02 '25 02:11

Barmar