Files and databases · GCSE · OCR J277 2.2.3, AQA 8525 3.7.1 · about 15 min
Tables, records, fields, primary and foreign keys, and avoiding redundancy.
[1 mark]In a database table, what is a record?
[1 mark]What is a primary key?
[1 mark]In the runs table, robot_id holds the primary key of a record in the robots table. What is robot_id in runs?
[1 mark]Ada's colour is typed into every one of her runs. What is this called?
[1 mark]Why is storing Ada's colour once, in a robots table, better?
[1 mark]Why would a robot's name make a poor primary key?
Using logbook.open_db(), print one line for every run, in run order, in the form run 1 by Ada: wall 42.0 cm. Look each robot's name up through the robot_id foreign key; do not type the names into your program.
# the two lines every program starts with: the commands, then the robot from bugbot import * connect() import logbook db = logbook.open_db()
The hint students can ask for: Build a dictionary from robot_id to name from SELECT * FROM robots, then loop over SELECT * FROM runs and look each robot_id up.
{'program': 'from bugbot import *\nconnect()\nimport logbook\n\ndb = logbook.open_db()\nnames = {}\nfor robot_id, name, colour in db.execute("SELECT * FROM robots"):\n names[robot_id] = name\nfor run_id, robot_id, task, cm, seconds in db.execute("SELECT * FROM runs ORDER BY run_id"):\n print(f"run {run_id} by {names[robot_id]}: {task} {cm} cm")\n', 'files': {'logbook.py': '# logbook.py: the class\'s robot runs as a relational database\nimport sqlite3\n\nROBOTS = [(1, "Ada", "green"), (2, "Bolt", "red"), (3, "Cog", "blue")]\nRUNS = [(1, 1, "wall", 42.0, 3.1), (2, 1, "square", 80.0, 9.4), (3, 2, "wall", 38.0, 2.7),\n (4, 1, "wall", 45.5, 3.0), (5, 3, "square", 76.5, 8.8), (6, 2, "square", 81.0, 10.2)]\n\ndef open_db():\n """A fresh database with the robots and runs tables."""\n db = sqlite3.connect(":memory:")\n db.execute("CREATE TABLE robots (robot_id INTEGER PRIMARY KEY, name TEXT, colour TEXT)")\n db.execute("CREATE TABLE runs (run_id INTEGER PRIMARY KEY, robot_id INTEGER REFERENCES robots(robot_id), "\n "task TEXT, cm REAL, seconds REAL)")\n db.executemany("INSERT INTO robots VALUES (?, ?, ?)", ROBOTS)\n db.executemany("INSERT INTO runs VALUES (?, ?, ?, ?, ?)", RUNS)\n return db\n\ndef show(db, sql):\n """Run a query and print each record on its own line."""\n for row in db.execute(sql):\n print(*row)\n'}}Any program that meets the task's checks is marked correct in the simulator; this is one way, not the only way.