-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexample.py
executable file
·116 lines (92 loc) · 3.06 KB
/
example.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/env python3
import sqlite3
from typing import Optional
from pydantic import BaseModel
from internal.doc import assert_output, fprint
# Define the schema for the database.
# This is executed every time the program is run, so we have to check if the
# table already exists.
DB_SCHEMA = """
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL,
password TEXT NOT NULL,
bio TEXT
);
"""
# Set the name of the database file.
# Ideally, use "database.db" or something similar, but for the sake of the
# example, we'll use ":memory:" to create a temporary database.
DB_FILE = ":memory:"
# Create a new SQLite database.
db = sqlite3.connect(DB_FILE, check_same_thread=False)
db.row_factory = sqlite3.Row
class User(BaseModel):
"""
This class represents a user.
It closely mirrors the database schema and allows us to easily work with
SQLite rows from that table.
"""
id: int
username: str
password: str
bio: Optional[str] = None
def main():
# First, set up the database by executing the schema.
db.executescript(DB_SCHEMA)
db.commit()
# Add some users.
db.execute(
"INSERT INTO users (username, password) VALUES (?, ?)",
("alice", "1234"),
)
db.execute(
"INSERT INTO users (username, password) VALUES (?, ?)",
("bob", "1234"),
)
db.commit()
# Print Alice.
# First, we fetch the row from the database.
# This returns a raw SQLite row object.
alice_row = db.execute(
"SELECT * FROM users WHERE username = ?",
("alice",),
).fetchone()
# Then, we parse the row into a User object.
alice = User(**alice_row)
# Finally, we print the user.
fprint("Alice:", alice)
# Do the same for all users. We can use list comprehension to make this
# more concise.
user_rows = db.execute("SELECT * FROM users").fetchall()
users = [User(**row) for row in user_rows]
fprint("Users:", users)
# Make our life easier by creating a function to fetch users.
def get_user(username: str) -> User | None:
row = db.execute(
"SELECT * FROM users WHERE username = ?",
(username,),
).fetchone()
# row may be None if the user does not exist.
return User(**row) if row else None
# Give Alice a bio.
db.execute("UPDATE users SET bio = ? WHERE username = ?", ("I am Alice", "alice"))
db.commit()
# Print Alice again to see the changes.
alice = get_user("alice")
fprint("Alice:", alice)
# Delete Bob.
db.execute("DELETE FROM users WHERE username = ?", ("bob",))
db.commit()
# Observe that Bob is gone.
bob = get_user("bob")
fprint("Bob:", bob)
output = """
Alice: id=1 username='alice' password='1234' bio=None
Users: [User(id=1, username='alice', password='1234', bio=None), User(id=2, username='bob', password='1234', bio=None)]
Alice: id=1 username='alice' password='1234' bio='I am Alice'
Bob: None
"""
if __name__ == "__main__":
main()
assert_output(output)