Level 1 Tables, rows, projection
Build Database. No SQL parsing: every operation is a plain method call.
create_table(table, columns) -> None:columnsis a list of distinct column names. RaiseValueErrorif the table already exists.insert(table, row) -> None:rowis a dict whose keys are exactly the table's columns (any order). RaiseValueErrorfor an unknown table or for missing or extra keys. Store a copy: changing the caller's dict afterwards must not change the table.query(table, columns) -> list[dict]: one dict per row, in insertion order, holding only the requested columns (keys in the order requested). RaiseValueErrorfor an unknown table or any unknown column. Returned dicts are fresh: editing them must not change the table.
db = Database()
db.create_table("users", ["id", "name", "age"])
db.insert("users", {"id": 1, "name": "Ann", "age": 31})
db.insert("users", {"name": "Bo", "id": 2, "age": 25})
db.query("users", ["name"]) # [{"name": "Ann"}, {"name": "Bo"}]
db.query("users", ["age", "id"]) # [{"age": 31, "id": 1}, {"age": 25, "id": 2}]
db.query("users", ["email"]) # ValueError