Skip to content

Commit 0ad8d99

Browse files
committed
Adding the example program files that go along with the python-sqlite-sqlalchemy article
1 parent 0471be2 commit 0ad8d99

File tree

24 files changed

+1371
-0
lines changed

24 files changed

+1371
-0
lines changed

python-sqlite-sqlalchemy/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Pythoh / Sqlite /SqlAlchemy article
2+
3+
This repository contains the content and example code
4+
for the python/sqlite/sqlaclchemy article I'm writing
5+
for Real Python.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Build Files Used By The Examples
2+
3+
The code in this directory builds the various data files used
4+
by the example programs. There are three build programs:
5+
6+
* build_temp_data_csv.py
7+
* build_temp_data_sqlite.py
8+
* build_author_book_publisher_sqlite.py
9+
10+
## Build the Temperature CSV File
11+
12+
The build_temp_data_csv.py file builds a CSV data file
13+
(temp_data.csv) in the data directory
14+
containing temperature samples taken by students in a class.
15+
The top row contains the labels, the students name followed
16+
by a date value for each Wednesday of the week for a year.
17+
18+
It then creates data for each sample based on a table of
19+
temperature data, +/- 10 to make the data look variable
20+
and reasonable.
21+
22+
## Build the Temperature Database File
23+
24+
The build_temp_data_sqlite.py file builds a Sqlite database
25+
from the previously created temp_data.csv file called
26+
temp_data.db in the data directory.
27+
28+
## Build the Author / Book / Publisher Database File
29+
30+
The build_author_book_publisher_sqlite.py file builds
31+
a database from the data/author_book_publisher.csv file.
32+
This database contains the tables necessary to describe
33+
the data and the relationships between the data necessary
34+
for the examples.
35+
36+
## Directory Structure
37+
38+
The directory structure is set up in such a way the
39+
build programs (as well as the examples) can find the
40+
data files needed for each one.
41+
42+
# Executing the Programs
43+
44+
* Activate your Python virtualenv
45+
* cd into the build/code directory
46+
* python build_temp_data_csv.py - builds the csv data file
47+
* python build_temp_data_sqlite.py - builds the temperature data from the csv file
48+
* python build_author_book_publisher_sqlite.py - builds the author_book_publisher.db database file
49+
50+
51+
52+
53+
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
"""
2+
This program builds the author_book_publisher Sqlite database from the
3+
author_book_publisher.csv file.
4+
"""
5+
6+
import os
7+
import csv
8+
from sqlalchemy import create_engine
9+
from sqlalchemy.orm import sessionmaker
10+
from lib.models import Base
11+
from lib.models import Author
12+
from lib.models import Book
13+
from lib.models import Publisher
14+
15+
16+
def get_author_book_publisher_data(filepath):
17+
"""
18+
This function gets the data from the csv file
19+
"""
20+
with open(filepath) as csvfile:
21+
csv_reader = csv.DictReader(csvfile)
22+
data = [row for row in csv_reader]
23+
return data
24+
25+
26+
def populate_database(session, author_book_publisher_data):
27+
# insert the data
28+
for row in author_book_publisher_data:
29+
30+
author = (
31+
session.query(Author).filter(
32+
Author.lname == row["lname"]).one_or_none()
33+
)
34+
if author is None:
35+
author = Author(fname=row["fname"], lname=row["lname"])
36+
session.add(author)
37+
38+
book = session.query(Book).filter(
39+
Book.title == row["title"]).one_or_none()
40+
if book is None:
41+
book = Book(title=row["title"])
42+
session.add(book)
43+
44+
publisher = (
45+
session.query(
46+
Publisher
47+
).filter(
48+
Publisher.name == row["publisher"]
49+
).one_or_none()
50+
)
51+
if publisher is None:
52+
publisher = Publisher(name=row["publisher"])
53+
session.add(publisher)
54+
55+
# add the items to the relationships
56+
author.books.append(book)
57+
author.publishers.append(publisher)
58+
publisher.authors.append(author)
59+
publisher.books.append(book)
60+
session.commit()
61+
62+
session.close()
63+
64+
65+
def main():
66+
print("starting")
67+
68+
# get the author/book/publisher data into a dictionary structure
69+
path = os.path.dirname(os.path.abspath(__file__))
70+
csv_filepath = os.path.join(path, "../data/author_book_publisher.csv")
71+
author_book_publisher_data = get_author_book_publisher_data(csv_filepath)
72+
73+
# get the filepath to the database file
74+
sqlite_filepath = os.path.join(path, "../data/author_book_publisher.db")
75+
76+
# does the database exist?
77+
if os.path.exists(sqlite_filepath):
78+
os.remove(sqlite_filepath)
79+
80+
# create the database
81+
engine = create_engine(f"sqlite:///{sqlite_filepath}")
82+
Base.metadata.create_all(engine)
83+
Session = sessionmaker()
84+
Session.configure(bind=engine)
85+
session = Session()
86+
populate_database(session, author_book_publisher_data)
87+
88+
print("finished")
89+
90+
91+
if __name__ == "__main__":
92+
main()
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import os
2+
import csv
3+
import datetime
4+
from random import randint
5+
6+
7+
start_date = datetime.datetime.strptime("2019-01-02", "%Y-%m-%d")
8+
9+
students = [
10+
"John",
11+
"Mary",
12+
"Susan",
13+
"Doug",
14+
"Andrew",
15+
"George",
16+
"Martha",
17+
"Paul",
18+
"Helen"
19+
]
20+
21+
temperature_data = [
22+
10, 12, 16, 23, 13,
23+
12, 14, 22, 25,
24+
28, 32, 33, 37,
25+
36, 35, 40, 44,
26+
45, 50, 52, 58, 60,
27+
66, 70, 70, 72,
28+
78, 80, 81, 82, 85,
29+
88, 90, 87, 90,
30+
85, 82, 81, 78,
31+
75, 72, 72, 70, 63,
32+
65, 62, 60, 45,
33+
40, 37, 30, 28
34+
]
35+
36+
37+
def offset_temp(temperature):
38+
"""
39+
This function modifies the temperature +/- a random
40+
amount up to 10
41+
:param temperature: temperature to modify
42+
:return: modified temperature
43+
"""
44+
return temperature + randint(-10, 10)
45+
46+
47+
def main():
48+
# create the CSV file
49+
path = os.path.dirname(os.path.abspath(__file__))
50+
csv_filepath = os.path.join(path, "../data/temp_data.csv")
51+
with open(csv_filepath, "w") as data_fh:
52+
53+
# create the writer
54+
csv_writer = csv.writer(data_fh)
55+
56+
# write the header
57+
header = ["name"]
58+
for week in range(0, 52):
59+
current_date = start_date + datetime.timedelta(days=week * 7)
60+
header.append(current_date.strftime("%Y-%m-%d"))
61+
csv_writer.writerow(header)
62+
63+
# iterate through the students and write their data
64+
for student in students:
65+
data = [student]
66+
# iterate through the weeks
67+
for week in range(0, 52):
68+
data.append(offset_temp(temperature_data[week]))
69+
70+
csv_writer.writerow(data)
71+
72+
73+
if __name__ == "__main__":
74+
main()
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
"""
2+
This program gathers information from the temp_data.db file about temperature
3+
"""
4+
5+
import os
6+
import csv
7+
from datetime import datetime
8+
from sqlalchemy import create_engine
9+
from sqlalchemy import Column, Integer, String, Date, Float
10+
from sqlalchemy.orm import sessionmaker
11+
from sqlalchemy.ext.declarative import declarative_base
12+
13+
14+
Base = declarative_base()
15+
16+
17+
class TemperatureData(Base):
18+
__tablename__ = "temperature_data"
19+
temperature_data_id = Column(Integer, primary_key=True)
20+
name = Column(String, nullable=False)
21+
date = Column(Date, nullable=False)
22+
value = Column(Float, nullable=False)
23+
24+
25+
def get_temperature_data(filepath):
26+
"""
27+
This function gets the temperature data from the csv file
28+
"""
29+
with open(filepath) as csvfile:
30+
csv_reader = csv.DictReader(csvfile)
31+
data = {
32+
row["name"]: row
33+
for row in csv_reader
34+
}
35+
for value in data.values():
36+
value.pop("name")
37+
return data
38+
39+
40+
def populate_database(session, temperature_data):
41+
# insert the data
42+
for student, data in temperature_data.items():
43+
for date, value in data.items():
44+
temp_data = TemperatureData(
45+
name=student,
46+
date=datetime.strptime(date, "%Y-%m-%d").date(),
47+
value=value
48+
)
49+
session.add(temp_data)
50+
session.commit()
51+
session.close()
52+
53+
54+
def main():
55+
print("starting")
56+
57+
# get the temperature data into a dictionary structure
58+
path = os.path.dirname(os.path.abspath(__file__))
59+
csv_filepath = os.path.join(path, "../data/temp_data.csv")
60+
temperature_data = get_temperature_data(csv_filepath)
61+
62+
# get the filepath to the database file
63+
sqlite_filepath = os.path.join(path, "../data/temp_data.db")
64+
65+
# does the database exist?
66+
if os.path.exists(sqlite_filepath):
67+
os.remove(sqlite_filepath)
68+
69+
# create and populate the sqlite database
70+
engine = create_engine(f"sqlite:///{sqlite_filepath}")
71+
Base.metadata.create_all(engine)
72+
Session = sessionmaker()
73+
Session.configure(bind=engine)
74+
session = Session()
75+
populate_database(session, temperature_data)
76+
77+
print("finished")
78+
79+
80+
if __name__ == "__main__":
81+
main()
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
fname,lname,title,publisher
2+
Issac,Asimov,Foundation,Random House
3+
Pearl,Buck,The Good Earth,Random House
4+
Pearl,Buck,The Good Earth,Simon & Schuster
5+
Tom,Clancy,The Hunt For Red October,Berkley
6+
Tom,Clancy,Patriot Games,Simon & Schuster
7+
Stephen,King,It,Random House
8+
Stephen,King,It,Penguin Random House
9+
Stephen,King,Dead Zone,Random House
10+
Stephen,King,The Shinning,Penguin Random House
11+
John,Le Carre,"Tinker, Tailor, Solider, Spy: A George Smiley Novel",Berkley
12+
Alex,Michaelides,The Silent Patient,Simon & Schuster
13+
Carol,Shaben,Into The Abyss,Simon & Schuster
Binary file not shown.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name,2019-01-02,2019-01-09,2019-01-16,2019-01-23,2019-01-30,2019-02-06,2019-02-13,2019-02-20,2019-02-27,2019-03-06,2019-03-13,2019-03-20,2019-03-27,2019-04-03,2019-04-10,2019-04-17,2019-04-24,2019-05-01,2019-05-08,2019-05-15,2019-05-22,2019-05-29,2019-06-05,2019-06-12,2019-06-19,2019-06-26,2019-07-03,2019-07-10,2019-07-17,2019-07-24,2019-07-31,2019-08-07,2019-08-14,2019-08-21,2019-08-28,2019-09-04,2019-09-11,2019-09-18,2019-09-25,2019-10-02,2019-10-09,2019-10-16,2019-10-23,2019-10-30,2019-11-06,2019-11-13,2019-11-20,2019-11-27,2019-12-04,2019-12-11,2019-12-18,2019-12-25
2+
John,4,17,13,18,19,17,22,16,34,36,29,28,28,41,40,40,40,39,56,48,55,63,58,61,63,78,71,79,87,76,93,86,84,81,84,93,91,71,77,71,65,62,68,69,74,62,68,38,45,33,34,36
3+
Mary,12,21,11,29,12,21,16,25,18,34,26,26,31,38,28,30,38,37,54,42,48,50,68,67,74,75,86,75,85,83,94,95,86,80,88,95,89,73,87,80,79,65,65,67,60,71,69,48,45,43,23,24
4+
Susan,7,18,22,22,6,11,7,20,17,36,32,33,27,33,42,33,44,47,46,43,50,63,63,65,73,71,71,89,77,76,79,93,95,89,87,94,92,80,82,73,65,63,77,63,64,70,69,54,45,38,21,34
5+
Doug,18,15,14,15,17,18,15,22,18,37,32,36,27,35,27,50,39,40,54,44,62,57,71,74,62,75,74,74,86,82,79,79,92,97,99,82,74,71,87,65,74,72,66,73,64,58,68,49,39,39,29,29
6+
Andrew,5,4,20,16,12,14,8,16,31,29,35,38,30,38,35,47,46,50,60,51,62,50,72,69,68,82,80,72,72,81,85,81,90,87,86,83,78,84,82,81,62,79,66,68,56,69,51,45,36,30,37,34
7+
George,17,14,15,26,18,22,17,13,32,31,36,31,46,44,32,35,34,47,43,47,62,70,75,63,64,65,76,71,75,83,78,88,88,88,99,75,86,91,80,72,79,80,60,64,71,70,51,51,36,28,37,22
8+
Martha,0,4,11,27,19,22,13,24,28,25,37,35,29,43,35,37,39,42,57,53,68,69,69,67,70,68,83,87,74,79,95,94,85,87,81,89,81,89,85,68,78,62,61,55,57,55,70,43,40,31,31,29
9+
Paul,1,20,15,27,11,20,12,29,26,30,27,29,40,34,45,45,45,51,51,46,68,56,67,73,66,79,77,88,85,83,88,79,81,81,98,76,89,76,86,73,63,70,72,68,61,62,67,35,39,35,26,31
10+
Helen,17,15,18,15,4,15,16,21,28,24,32,35,35,29,28,43,54,40,41,60,60,63,65,74,79,74,82,72,78,81,86,86,81,90,91,86,83,80,80,81,80,67,75,73,58,52,51,37,38,46,34,26
20 KB
Binary file not shown.

python-sqlite-sqlalchemy/build_data/data/temperature_data.db

Whitespace-only changes.

0 commit comments

Comments
 (0)