├── .gitignore ├── .gitpod.dockerfile ├── .gitpod.yml ├── .vscode ├── font_fix.py ├── heroku_config.sh ├── init_tasks.sh ├── launch.json ├── settings.json ├── since_update.sh └── snippets.json ├── 01_installing_the_chinook_database ├── COMMANDS.md └── Chinook_PostgreSql.sql ├── 02_postgresql_from_the_command_line ├── COMMANDS.md ├── test.csv └── test.json ├── 03_installing_the_libraries_and_setting_up ├── COMMANDS.md └── sql-psycopg2.py ├── 04_introducing_an_orm └── COMMANDS.md ├── 05_running_basic_queries ├── COMMANDS.md └── sql-expression.py ├── 06_introducing_class_based_models ├── COMMANDS.md └── sql-orm.py ├── 07_codealong_create_and_read ├── CHALLENGE.md ├── COMMANDS.md └── sql-crud.py ├── 08_codealong_update_and_delete ├── CHALLENGE.md └── sql-crud.py └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | core.Microsoft* 2 | core.mongo* 3 | core.python* 4 | env.py 5 | __pycache__/ 6 | *.py[cod] 7 | node_modules/ 8 | -------------------------------------------------------------------------------- /.gitpod.dockerfile: -------------------------------------------------------------------------------- 1 | FROM gitpod/workspace-postgres 2 | 3 | USER root 4 | # Setup Heroku CLI 5 | RUN curl https://cli-assets.heroku.com/install.sh | sh 6 | 7 | # Setup Python linters 8 | RUN pip3 install flake8 flake8-flask flake8-django 9 | 10 | USER gitpod 11 | 12 | # Upgrade Node 13 | 14 | ENV NODE_VERSION=14.15.4 15 | RUN bash -c ". .nvm/nvm.sh && \ 16 | nvm install ${NODE_VERSION} && \ 17 | nvm alias default ${NODE_VERSION} && \ 18 | npm install -g yarn" 19 | 20 | RUN echo 'alias heroku_config=". $GITPOD_REPO_ROOT/.vscode/heroku_config.sh"' >> ~/.bashrc 21 | RUN echo 'alias run="python3 $GITPOD_REPO_ROOT/manage.py runserver 0.0.0.0:8000"' >> ~/.bashrc 22 | RUN echo 'alias python=python3' >> ~/.bashrc 23 | RUN echo 'alias pip=pip3' >> ~/.bashrc 24 | RUN echo 'alias font_fix="python3 $GITPOD_REPO_ROOT/.vscode/font_fix.py"' >> ~/.bashrc 25 | ENV PATH=/home/gitpod/.nvm/versions/node/v${NODE_VERSION}/bin:$PATH 26 | 27 | # Local environment variables 28 | 29 | ENV PORT="8080" 30 | ENV IP="0.0.0.0" 31 | 32 | USER root 33 | # Switch back to root to allow IDE to load 34 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | image: 2 | file: .gitpod.dockerfile 3 | tasks: 4 | - init: . ${GITPOD_REPO_ROOT}/.vscode/init_tasks.sh 5 | vscode: 6 | extensions: 7 | - ms-python.python 8 | - formulahendry.auto-close-tag 9 | - mkaufman.HTMLHint 10 | - eventyret.bootstrap-4-cdn-snippet 11 | - kevinglasson.cornflakes-linter 12 | - hookyqr.beautify 13 | -------------------------------------------------------------------------------- /.vscode/font_fix.py: -------------------------------------------------------------------------------- 1 | # Fixes the font issue on Brave browser 2 | # Matt Rudge 3 | # June 2021 4 | 5 | import json 6 | import os 7 | 8 | BASE_PATH = os.environ.get("GITPOD_REPO_ROOT") 9 | 10 | with open(f"{BASE_PATH}/.vscode/settings.json", "r+") as f: 11 | content = json.loads(f.read()) 12 | 13 | if "terminal.integrated.fontFamily" not in content: 14 | print("Terminal Font Fix: adding Menlo font") 15 | content["terminal.integrated.fontFamily"] = "Menlo" 16 | else: 17 | print("Terminal Font Fix: removing Menlo font") 18 | content.pop("terminal.integrated.fontFamily") 19 | 20 | f.seek(0, os.SEEK_SET) 21 | f.write(json.dumps(content)) 22 | f.truncate() 23 | -------------------------------------------------------------------------------- /.vscode/heroku_config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Script to allow Heroku API key to be pasted 3 | # exported as an environment variable 4 | # 5 | # Matt Rudge, May 2021 6 | 7 | echo Heroku authentication configuration script 8 | echo Code Institute, 2021 9 | echo 10 | echo Get your Heroku API key by going to https://dashboard.heroku.com 11 | echo Go to Account Settings and click on Reveal to view your Heroku API key 12 | echo 13 | 14 | if [[ -z "${HEROKU_API_KEY}" ]]; then 15 | echo Paste your Heroku API key here or press Enter to quit: 16 | read apikey 17 | if [[ -z "${apikey}" ]]; then 18 | return 0 19 | fi 20 | echo export HEROKU_API_KEY=${apikey} >> ~/.bashrc 21 | echo Added the export. Refreshing the terminal. 22 | . ~/.bashrc > /dev/null 23 | echo Done! 24 | else 25 | echo API key is already set. Exiting 26 | fi 27 | -------------------------------------------------------------------------------- /.vscode/init_tasks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Gives a personalised greeting 4 | # Adds configuration options for SQLite 5 | # Creates run aliases 6 | # Author: Matt Rudge 7 | 8 | clear 9 | echo "Setting the greeting" 10 | sed -i "s/USER_NAME/$GITPOD_GIT_USER_NAME/g" ${GITPOD_REPO_ROOT}/README.md 11 | echo "Creating .sqliterc file" 12 | echo ".headers on" > ~/.sqliterc 13 | echo ".mode column" >> ~/.sqliterc 14 | echo "Your workspace is ready to use. Happy coding!" 15 | source ~/.bashrc 16 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | "version": "0.2.0", 5 | "configurations": [ 6 | { 7 | "name": "Python: Current File (Integrated Terminal)", 8 | "type": "python", 9 | "request": "launch", 10 | "program": "${file}", 11 | "console": "internalConsole" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.linting.pylintEnabled": true, 3 | "python.linting.enabled": true, 4 | "python.linting.pep8Enabled": false, 5 | "python.linting.flake8Enabled": true, 6 | "python.terminal.activateEnvironment": false, 7 | "python.formatting.autopep8Path": "/home/gitpod/.pyenv/shims/autopep8", 8 | "python.linting.flake8Path": "/home/gitpod/.pyenv/shims/flake8", 9 | "cornflakes.linter.executablePath": "/home/gitpod/.pyenv/shims/flake8", 10 | "files.exclude": { 11 | "**/.DS_Store": true, 12 | "**/.git": true, 13 | "**/.github": true, 14 | "**/.gitp*": true, 15 | "**/.hg": true, 16 | "**/.svn": true, 17 | "**/.vscode": true, 18 | "**/core.Microsoft*": true, 19 | "**/core.mongo*": true, 20 | "**/core.python*": true, 21 | "**/CVS": true 22 | }, 23 | "files.autoSave": "off", 24 | "workbench.colorTheme": "Visual Studio Dark", 25 | "editor.defaultFormatter": "HookyQR.beautify" 26 | } 27 | -------------------------------------------------------------------------------- /.vscode/since_update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Post update script, add in changes to init_tasks.sh 3 | # that won't take effect in an upgraded workspace 4 | 5 | echo 'alias heroku_config=". $GITPOD_REPO_ROOT/.vscode/heroku_config.sh"' >> ~/.bashrc 6 | 7 | echo Post-upgrade changes applied 8 | -------------------------------------------------------------------------------- /.vscode/snippets.json: -------------------------------------------------------------------------------- 1 | { 2 | "html": { 3 | "snippets": { 4 | "form": "form>input>input:submit[value=\"Submit\"]" 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /01_installing_the_chinook_database/COMMANDS.md: -------------------------------------------------------------------------------- 1 | # 01 - Installing the Chinook Database 2 | 3 | --- 4 | 5 | ### Download the Chinook PostgreSql database 6 | - [source](https://github.com/Code-Institute-Solutions/postgresql-and-python/blob/main/01_installing_the_chinook_database/Chinook_PostgreSql.sql) 7 | - `wget https://raw.githubusercontent.com/Code-Institute-Solutions/postgresql-and-python/main/01_installing_the_chinook_database/Chinook_PostgreSql.sql` 8 | 9 | ### Access the Postgres CLI 10 | - `psql` 11 | 12 | ### Create the new "chinook" database 13 | - `CREATE DATABASE chinook;` 14 | 15 | ### View existing tables on the database 16 | - `\l` 17 | 18 | ### Switch between databases 19 | - `\c postgres` (switch to the database called "postgres") 20 | - `\c chinook` (switch to the database called "chinook") 21 | 22 | ### Install / Initialize the downloaded Chinook SQL database 23 | - `\i Chinook_PostgreSql.sql` (takes several minutes) 24 | -------------------------------------------------------------------------------- /01_installing_the_chinook_database/Chinook_PostgreSql.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Code-Institute-Solutions/postgresql-and-python/735eba82d61dee9d298722eb8dceaac7e7ecfb6d/01_installing_the_chinook_database/Chinook_PostgreSql.sql -------------------------------------------------------------------------------- /02_postgresql_from_the_command_line/COMMANDS.md: -------------------------------------------------------------------------------- 1 | # 02 - PostgreSQL from the Command Line 2 | 3 | --- 4 | 5 | ### Quit the entire Postgres CLI 6 | - `\q` 7 | 8 | ### Connect to the "chinook" Postgres CLI database 9 | - `psql -d chinook` 10 | 11 | ### Display all tables on the "chinook" database 12 | - `\dt` 13 | 14 | ### Quit the query / return back to CLI after a query 15 | - `q` 16 | 17 | ### Retrieve all data from the "Artist" table 18 | - `SELECT * FROM "Artist";` 19 | 20 | ### Retrieve only the "Name" column from the "Artist" table 21 | - `SELECT "Name" FROM "Artist";` 22 | 23 | ### Retrieve only "Queen" from the "Artist" table 24 | - `SELECT * FROM "Artist" WHERE "Name" = 'Queen';` 25 | 26 | ### Retrieve only "Queen" from the "Artist" table, but using the "ArtistId" of '51' 27 | - `SELECT * FROM "Artist" WHERE "ArtistId" = 51;` 28 | 29 | ### Retrieve all albums from the "Album" table, using the "ArtistId" of '51' 30 | - `SELECT * FROM "Album" WHERE "ArtistId" = 51;` 31 | 32 | ### Retrieve all tracks from the "Track" table, using the "Composer" of 'Queen' 33 | - `SELECT * FROM "Track" WHERE "Composer" = 'Queen';` 34 | 35 | --- 36 | 37 | ## OPTIONAL 38 | 39 | ### Copy the results into a .CSV file 40 | - `\copy (SELECT * FROM "Track" WHERE "Composer" = 'Queen') TO 'test.csv' WITH CSV DELIMITER ',' HEADER;` 41 | 42 | ### Copy the results into a .JSON file 43 | - Line 1: `\o test.json` 44 | - Line 2: `SELECT json_agg(t) FROM (SELECT * FROM "Track" WHERE "Composer" = 'Queen') t;` 45 | -------------------------------------------------------------------------------- /02_postgresql_from_the_command_line/test.csv: -------------------------------------------------------------------------------- 1 | TrackId,Name,AlbumId,MediaTypeId,GenreId,Composer,Milliseconds,Bytes,UnitPrice 2 | 422,I Want It All,36,1,1,Queen,241684,7876564,0.99 3 | 424,Innuendo,36,1,1,Queen,387761,12664591,0.99 4 | 426,Breakthru,36,1,1,Queen,249234,8150479,0.99 5 | 428,Headlong,36,1,1,Queen,273057,8921404,0.99 6 | 429,The Miracle,36,1,1,Queen,294974,9671923,0.99 7 | 430,I'm Going Slightly Mad,36,1,1,Queen,248032,8192339,0.99 8 | 431,The Invisible Man,36,1,1,Queen,238994,7920353,0.99 9 | 434,The Show Must Go On,36,1,1,Queen,263784,8526760,0.99 10 | 435,One Vision,36,1,1,Queen,242599,7936928,0.99 11 | -------------------------------------------------------------------------------- /02_postgresql_from_the_command_line/test.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "TrackId":422, 4 | "Name":"I Want It All", 5 | "AlbumId":36, 6 | "MediaTypeId":1, 7 | "GenreId":1, 8 | "Composer":"Queen", 9 | "Milliseconds":241684, 10 | "Bytes":7876564, 11 | "UnitPrice":0.99 12 | }, 13 | { 14 | "TrackId":424, 15 | "Name":"Innuendo", 16 | "AlbumId":36, 17 | "MediaTypeId":1, 18 | "GenreId":1, 19 | "Composer":"Queen", 20 | "Milliseconds":387761, 21 | "Bytes":12664591, 22 | "UnitPrice":0.99 23 | }, 24 | { 25 | "TrackId":426, 26 | "Name":"Breakthru", 27 | "AlbumId":36, 28 | "MediaTypeId":1, 29 | "GenreId":1, 30 | "Composer":"Queen", 31 | "Milliseconds":249234, 32 | "Bytes":8150479, 33 | "UnitPrice":0.99 34 | }, 35 | { 36 | "TrackId":428, 37 | "Name":"Headlong", 38 | "AlbumId":36, 39 | "MediaTypeId":1, 40 | "GenreId":1, 41 | "Composer":"Queen", 42 | "Milliseconds":273057, 43 | "Bytes":8921404, 44 | "UnitPrice":0.99 45 | }, 46 | { 47 | "TrackId":429, 48 | "Name":"The Miracle", 49 | "AlbumId":36, 50 | "MediaTypeId":1, 51 | "GenreId":1, 52 | "Composer":"Queen", 53 | "Milliseconds":294974, 54 | "Bytes":9671923, 55 | "UnitPrice":0.99 56 | }, 57 | { 58 | "TrackId":430, 59 | "Name":"I'm Going Slightly Mad", 60 | "AlbumId":36, 61 | "MediaTypeId":1, 62 | "GenreId":1, 63 | "Composer":"Queen", 64 | "Milliseconds":248032, 65 | "Bytes":8192339, 66 | "UnitPrice":0.99 67 | }, 68 | { 69 | "TrackId":431, 70 | "Name":"The Invisible Man", 71 | "AlbumId":36, 72 | "MediaTypeId":1, 73 | "GenreId":1, 74 | "Composer":"Queen", 75 | "Milliseconds":238994, 76 | "Bytes":7920353, 77 | "UnitPrice":0.99 78 | }, 79 | { 80 | "TrackId":434, 81 | "Name":"The Show Must Go On", 82 | "AlbumId":36, 83 | "MediaTypeId":1, 84 | "GenreId":1, 85 | "Composer":"Queen", 86 | "Milliseconds":263784, 87 | "Bytes":8526760, 88 | "UnitPrice":0.99 89 | }, 90 | { 91 | "TrackId":435, 92 | "Name":"One Vision", 93 | "AlbumId":36, 94 | "MediaTypeId":1, 95 | "GenreId":1, 96 | "Composer":"Queen", 97 | "Milliseconds":242599, 98 | "Bytes":7936928, 99 | "UnitPrice":0.99 100 | } 101 | ] 102 | -------------------------------------------------------------------------------- /03_installing_the_libraries_and_setting_up/COMMANDS.md: -------------------------------------------------------------------------------- 1 | # 03 - Installing the Libraries and Setting Up 2 | 3 | --- 4 | 5 | ### Install the "psycopg2" Python package 6 | - `pip3 install psycopg2` 7 | 8 | ### Create a new file: "sql-psycopg2.py" 9 | - `touch sql-psycopg2.py` 10 | -------------------------------------------------------------------------------- /03_installing_the_libraries_and_setting_up/sql-psycopg2.py: -------------------------------------------------------------------------------- 1 | import psycopg2 2 | 3 | 4 | # connect to "chinook" database 5 | connection = psycopg2.connect(database="chinook") 6 | 7 | # build a cursor object of the database 8 | cursor = connection.cursor() 9 | 10 | # Query 1 - select all records from the "Artist" table 11 | # cursor.execute('SELECT * FROM "Artist"') 12 | 13 | # Query 2 - select only the "Name" column from the "Artist" table 14 | # cursor.execute('SELECT "Name" FROM "Artist"') 15 | 16 | # Query 3 - select only "Queen" from the "Artist" table 17 | # cursor.execute('SELECT * FROM "Artist" WHERE "Name" = %s', ["Queen"]) 18 | 19 | # Query 4 - select only by "ArtistId" #51 from the "Artist" table 20 | # cursor.execute('SELECT * FROM "Artist" WHERE "ArtistId" = %s', [51]) 21 | 22 | # Query 5 - select only the albums with "ArtistId" #51 on the "Album" table 23 | # cursor.execute('SELECT * FROM "Album" WHERE "ArtistId" = %s', [51]) 24 | 25 | # Query 6 - select all tracks where the composer is "Queen" from the "Track" table 26 | cursor.execute('SELECT * FROM "Track" WHERE "Composer" = %s', ["Queen"]) 27 | 28 | # fetch the results (multiple) 29 | results = cursor.fetchall() 30 | 31 | # fetch the result (single) 32 | # results = cursor.fetchone() 33 | 34 | # close the connection 35 | connection.close() 36 | 37 | # print results 38 | for result in results: 39 | print(result) 40 | -------------------------------------------------------------------------------- /04_introducing_an_orm/COMMANDS.md: -------------------------------------------------------------------------------- 1 | # 04 - Introducing an ORM 2 | 3 | --- 4 | 5 | ### Install the "SQLAlchemy" Python package 6 | - `pip3 install SQLAlchemy` 7 | -------------------------------------------------------------------------------- /05_running_basic_queries/COMMANDS.md: -------------------------------------------------------------------------------- 1 | # 05 - Running Basic Queries 2 | 3 | --- 4 | 5 | ### Create a new file called "sql-expression.py" 6 | - `touch sql-expression.py` 7 | 8 | ### Query 1 - select all records from the "Artist" table 9 | - `select_query = artist_table.select()` 10 | 11 | ### Query 2 - select only the "Name" column from the "Artist" table 12 | - `select_query = artist_table.select().with_only_columns([artist_table.c.Name])` 13 | 14 | ### Query 3 - select only 'Queen' from the "Artist" table 15 | - `select_query = artist_table.select().where(artist_table.c.Name == "Queen")` 16 | 17 | ### Query 4 - select only by 'ArtistId' #51 from the "Artist" table 18 | - `select_query = artist_table.select().where(artist_table.c.ArtistId == 51)` 19 | 20 | ### Query 5 - select only the albums with 'ArtistId' #51 on the "Album" table 21 | - `select_query = album_table.select().where(album_table.c.ArtistId == 51)` 22 | 23 | ### Query 6 - select all tracks where the composer is 'Queen' from the "Track" table 24 | - `select_query = track_table.select().where(track_table.c.Composer == "Queen")` 25 | -------------------------------------------------------------------------------- /05_running_basic_queries/sql-expression.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import ( 2 | create_engine, Table, Column, Float, ForeignKey, Integer, String, MetaData 3 | ) 4 | 5 | # executing the instructions from our localhost "chinook" db 6 | db = create_engine("postgresql:///chinook") 7 | 8 | meta = MetaData(db) 9 | 10 | # create variable for "Artist" table 11 | artist_table = Table( 12 | "Artist", meta, 13 | Column("ArtistId", Integer, primary_key=True), 14 | Column("Name", String) 15 | ) 16 | 17 | # create variable for "Album" table 18 | album_table = Table( 19 | "Album", meta, 20 | Column("AlbumId", Integer, primary_key=True), 21 | Column("Title", String), 22 | Column("ArtistId", Integer, ForeignKey("artist_table.ArtistId")) 23 | ) 24 | 25 | # create variable for "Track" table 26 | track_table = Table( 27 | "Track", meta, 28 | Column("TrackId", Integer, primary_key=True), 29 | Column("Name", String), 30 | Column("AlbumId", Integer, ForeignKey("album_table.AlbumId")), 31 | Column("MediaTypeId", Integer, primary_key=False), 32 | Column("GenreId", Integer, primary_key=False), 33 | Column("Composer", String), 34 | Column("Milliseconds", Integer), 35 | Column("Bytes", Integer), 36 | Column("UnitPrice", Float) 37 | ) 38 | 39 | # making the connection 40 | with db.connect() as connection: 41 | 42 | # Query 1 - select all records from the "Artist" table 43 | # select_query = artist_table.select() 44 | 45 | # Query 2 - select only the "Name" column from the "Artist" table 46 | # select_query = artist_table.select().with_only_columns([artist_table.c.Name]) 47 | 48 | # Query 3 - select only 'Queen' from the "Artist" table 49 | # select_query = artist_table.select().where(artist_table.c.Name == "Queen") 50 | 51 | # Query 4 - select only by 'ArtistId' #51 from the "Artist" table 52 | # select_query = artist_table.select().where(artist_table.c.ArtistId == 51) 53 | 54 | # Query 5 - select only the albums with 'ArtistId' #51 on the "Album" table 55 | # select_query = album_table.select().where(album_table.c.ArtistId == 51) 56 | 57 | # Query 6 - select all tracks where the composer is 'Queen' from the "Track" table 58 | select_query = track_table.select().where(track_table.c.Composer == "Queen") 59 | 60 | results = connection.execute(select_query) 61 | for result in results: 62 | print(result) 63 | -------------------------------------------------------------------------------- /06_introducing_class_based_models/COMMANDS.md: -------------------------------------------------------------------------------- 1 | # 06 - Introducing Class-Based Models 2 | 3 | --- 4 | 5 | ### Create a new file called "sql-orm.py" 6 | - `touch sql-orm.py` 7 | 8 | ### Query 1 - select all records from the "Artist" table 9 | ```python 10 | artists = session.query(Artist) 11 | for artist in artists: 12 | print(artist.ArtistId, artist.Name, sep=" | ") 13 | ``` 14 | 15 | ### Query 2 - select only the "Name" column from the "Artist" table 16 | ```python 17 | artists = session.query(Artist) 18 | for artist in artists: 19 | print(artist.Name) 20 | ``` 21 | 22 | ### Query 3 - select only "Queen" from the "Artist" table 23 | ```python 24 | artist = session.query(Artist).filter_by(Name="Queen").first() 25 | print(artist.ArtistId, artist.Name, sep=" | ") 26 | ``` 27 | 28 | ### Query 4 - select only by "ArtistId" #51 from the "Artist" table 29 | ```python 30 | artist = session.query(Artist).filter_by(ArtistId=51).first() 31 | print(artist.ArtistId, artist.Name, sep=" | ") 32 | ``` 33 | 34 | ### Query 5 - select only the albums with "ArtistId" #51 on the "Album" table 35 | ```python 36 | albums = session.query(Album).filter_by(ArtistId=51) 37 | for album in albums: 38 | print(album.AlbumId, album.Title, album.ArtistId, sep=" | ") 39 | ``` 40 | 41 | ### Query 6 - select all tracks where the composer is "Queen" from the "Track" table 42 | ```python 43 | tracks = session.query(Track).filter_by(Composer="Queen") 44 | for track in tracks: 45 | print( 46 | track.TrackId, 47 | track.Name, 48 | track.AlbumId, 49 | track.MediaTypeId, 50 | track.GenreId, 51 | track.Composer, 52 | track.Milliseconds, 53 | track.Bytes, 54 | track.UnitPrice, 55 | sep=" | " 56 | ) 57 | ``` 58 | -------------------------------------------------------------------------------- /06_introducing_class_based_models/sql-orm.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import ( 2 | create_engine, Column, Float, ForeignKey, Integer, String 3 | ) 4 | from sqlalchemy.ext.declarative import declarative_base 5 | from sqlalchemy.orm import sessionmaker 6 | 7 | 8 | # executing the instructions from the "chinook" database 9 | db = create_engine("postgresql:///chinook") 10 | base = declarative_base() 11 | 12 | 13 | # create a class-based model for the "Artist" table 14 | class Artist(base): 15 | __tablename__ = "Artist" 16 | ArtistId = Column(Integer, primary_key=True) 17 | Name = Column(String) 18 | 19 | 20 | # create a class-based model for the "Album" table 21 | class Album(base): 22 | __tablename__ = "Album" 23 | AlbumId = Column(Integer, primary_key=True) 24 | Title = Column(String) 25 | ArtistId = Column(Integer, ForeignKey("Artist.ArtistId")) 26 | 27 | 28 | # create a class-based model for the "Track" table 29 | class Track(base): 30 | __tablename__ = "Track" 31 | TrackId = Column(Integer, primary_key=True) 32 | Name = Column(String) 33 | AlbumId = Column(Integer, ForeignKey("Album.AlbumId")) 34 | MediaTypeId = Column(Integer, primary_key=False) 35 | GenreId = Column(Integer, primary_key=False) 36 | Composer = Column(String) 37 | Milliseconds = Column(Integer, primary_key=False) 38 | Bytes = Column(Integer, primary_key=False) 39 | UnitPrice = Column(Float) 40 | 41 | 42 | # instead of connecting to the database directly, we will ask for a session 43 | # create a new instance of sessionmaker, then point to our engine (the db) 44 | Session = sessionmaker(db) 45 | # opens an actual session by calling the Session() subclass defined above 46 | session = Session() 47 | 48 | # creating the database using declarative_base subclass 49 | base.metadata.create_all(db) 50 | 51 | 52 | # Query 1 - select all records from the "Artist" table 53 | # artists = session.query(Artist) 54 | # for artist in artists: 55 | # print(artist.ArtistId, artist.Name, sep=" | ") 56 | 57 | # Query 2 - select only the "Name" column from the "Artist" table 58 | # artists = session.query(Artist) 59 | # for artist in artists: 60 | # print(artist.Name) 61 | 62 | # Query 3 - select only "Queen" from the "Artist" table 63 | # artist = session.query(Artist).filter_by(Name="Queen").first() 64 | # print(artist.ArtistId, artist.Name, sep=" | ") 65 | 66 | # Query 4 - select only by "ArtistId" #51 from the "Artist" table 67 | # artist = session.query(Artist).filter_by(ArtistId=51).first() 68 | # print(artist.ArtistId, artist.Name, sep=" | ") 69 | 70 | # Query 5 - select only the albums with "ArtistId" #51 on the "Album" table 71 | # albums = session.query(Album).filter_by(ArtistId=51) 72 | # for album in albums: 73 | # print(album.AlbumId, album.Title, album.ArtistId, sep=" | ") 74 | 75 | # Query 6 - select all tracks where the composer is "Queen" from the "Track" table 76 | tracks = session.query(Track).filter_by(Composer="Queen") 77 | for track in tracks: 78 | print( 79 | track.TrackId, 80 | track.Name, 81 | track.AlbumId, 82 | track.MediaTypeId, 83 | track.GenreId, 84 | track.Composer, 85 | track.Milliseconds, 86 | track.Bytes, 87 | track.UnitPrice, 88 | sep=" | " 89 | ) 90 | -------------------------------------------------------------------------------- /07_codealong_create_and_read/CHALLENGE.md: -------------------------------------------------------------------------------- 1 | # 07 - CodeAlong: Create and Read 2 | 3 | --- 4 | 5 | ### Your Challenge 6 | - Create a new record for yourself on the Programmer table. 7 | 8 | ### Reminders 9 | - Remember to comment-out your previous session(s) to avoid duplicates. 10 | - The key of `famous_for` can be anything you'd like to celebrate about yourself. 11 | - Once added, your record should have the primary_key of `7`, if following along. 12 | - Don't panicif your primary_key isn't `7`, just make note of the actual PK for later. 13 | -------------------------------------------------------------------------------- /07_codealong_create_and_read/COMMANDS.md: -------------------------------------------------------------------------------- 1 | # 07 - CodeAlong: Create and Read 2 | 3 | --- 4 | 5 | ### Create a new file called "sql-crud.py" 6 | - `touch sql-crud.py` 7 | -------------------------------------------------------------------------------- /07_codealong_create_and_read/sql-crud.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import ( 2 | create_engine, Column, Integer, String 3 | ) 4 | from sqlalchemy.ext.declarative import declarative_base 5 | from sqlalchemy.orm import sessionmaker 6 | 7 | 8 | # executing the instructions from the "chinook" database 9 | db = create_engine("postgresql:///chinook") 10 | base = declarative_base() 11 | 12 | 13 | # create a class-based model for the "Programmer" table 14 | class Programmer(base): 15 | __tablename__ = "Programmer" 16 | id = Column(Integer, primary_key=True) 17 | first_name = Column(String) 18 | last_name = Column(String) 19 | gender = Column(String) 20 | nationality = Column(String) 21 | famous_for = Column(String) 22 | 23 | 24 | # instead of connecting to the database directly, we will ask for a session 25 | # create a new instance of sessionmaker, then point to our engine (the db) 26 | Session = sessionmaker(db) 27 | # opens an actual session by calling the Session() subclass defined above 28 | session = Session() 29 | 30 | # creating the database using declarative_base subclass 31 | base.metadata.create_all(db) 32 | 33 | 34 | # creating records on our Progammer table 35 | ada_lovelace = Programmer( 36 | first_name="Ada", 37 | last_name="Lovelace", 38 | gender="F", 39 | nationality="British", 40 | famous_for="First Programmer" 41 | ) 42 | 43 | alan_turing = Programmer( 44 | first_name="Alan", 45 | last_name="Turing", 46 | gender="M", 47 | nationality="British", 48 | famous_for="Modern Computing" 49 | ) 50 | 51 | grace_hopper = Programmer( 52 | first_name="Grace", 53 | last_name="Hopper", 54 | gender="F", 55 | nationality="American", 56 | famous_for="COBOL language" 57 | ) 58 | 59 | margaret_hamilton = Programmer( 60 | first_name="Margaret", 61 | last_name="Hamilton", 62 | gender="F", 63 | nationality="American", 64 | famous_for="Apollo 11" 65 | ) 66 | 67 | bill_gates = Programmer( 68 | first_name="Bill", 69 | last_name="Gates", 70 | gender="M", 71 | nationality="American", 72 | famous_for="Microsoft" 73 | ) 74 | 75 | tim_berners_lee = Programmer( 76 | first_name="Tim", 77 | last_name="Berners-Lee", 78 | gender="M", 79 | nationality="British", 80 | famous_for="World Wide Web" 81 | ) 82 | 83 | # add each instance of our programmers to our session 84 | # session.add(ada_lovelace) 85 | # session.add(alan_turing) 86 | # session.add(grace_hopper) 87 | # session.add(margaret_hamilton) 88 | # session.add(bill_gates) 89 | # session.add(tim_berners_lee) 90 | 91 | # commit our session to the database 92 | # session.commit() 93 | 94 | 95 | # query the database to find all Programmers 96 | programmers = session.query(Programmer) 97 | for programmer in programmers: 98 | print( 99 | programmer.id, 100 | programmer.first_name + " " + programmer.last_name, 101 | programmer.gender, 102 | programmer.nationality, 103 | programmer.famous_for, 104 | sep=" | " 105 | ) 106 | -------------------------------------------------------------------------------- /08_codealong_update_and_delete/CHALLENGE.md: -------------------------------------------------------------------------------- 1 | # 08 - CodeAlong: Update and Delete 2 | 3 | --- 4 | 5 | ### Your Challenge 6 | - Continue building new tables and performing CRUD functionality. 7 | - Practice Makes Perfect! 8 | 9 | ### Reminders / Ideas 10 | - Remember to comment-out your previous command(s)/session(s). 11 | - A table for **your favorite places** (country name, capital city, population, etc.) 12 | - A table for **your favorite games** (release year, console name, etc.) 13 | - Remember to test the various CRUD functionalities. 14 | -------------------------------------------------------------------------------- /08_codealong_update_and_delete/sql-crud.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import ( 2 | create_engine, Column, Integer, String 3 | ) 4 | from sqlalchemy.ext.declarative import declarative_base 5 | from sqlalchemy.orm import sessionmaker 6 | 7 | 8 | # executing the instructions from the "chinook" database 9 | db = create_engine("postgresql:///chinook") 10 | base = declarative_base() 11 | 12 | 13 | # create a class-based model for the "Programmer" table 14 | class Programmer(base): 15 | __tablename__ = "Programmer" 16 | id = Column(Integer, primary_key=True) 17 | first_name = Column(String) 18 | last_name = Column(String) 19 | gender = Column(String) 20 | nationality = Column(String) 21 | famous_for = Column(String) 22 | 23 | 24 | # instead of connecting to the database directly, we will ask for a session 25 | # create a new instance of sessionmaker, then point to our engine (the db) 26 | Session = sessionmaker(db) 27 | # opens an actual session by calling the Session() subclass defined above 28 | session = Session() 29 | 30 | # creating the database using declarative_base subclass 31 | base.metadata.create_all(db) 32 | 33 | 34 | # creating records on our Progammer table 35 | ada_lovelace = Programmer( 36 | first_name="Ada", 37 | last_name="Lovelace", 38 | gender="F", 39 | nationality="British", 40 | famous_for="First Programmer" 41 | ) 42 | 43 | alan_turing = Programmer( 44 | first_name="Alan", 45 | last_name="Turing", 46 | gender="M", 47 | nationality="British", 48 | famous_for="Modern Computing" 49 | ) 50 | 51 | grace_hopper = Programmer( 52 | first_name="Grace", 53 | last_name="Hopper", 54 | gender="F", 55 | nationality="American", 56 | famous_for="COBOL language" 57 | ) 58 | 59 | margaret_hamilton = Programmer( 60 | first_name="Margaret", 61 | last_name="Hamilton", 62 | gender="F", 63 | nationality="American", 64 | famous_for="Apollo 11" 65 | ) 66 | 67 | bill_gates = Programmer( 68 | first_name="Bill", 69 | last_name="Gates", 70 | gender="M", 71 | nationality="American", 72 | famous_for="Microsoft" 73 | ) 74 | 75 | tim_berners_lee = Programmer( 76 | first_name="Tim", 77 | last_name="Berners-Lee", 78 | gender="M", 79 | nationality="British", 80 | famous_for="World Wide Web" 81 | ) 82 | 83 | your_name = Programmer( 84 | first_name="Your First Name", 85 | last_name="Your Last Name", 86 | gender="Your Gender", 87 | nationality="Your Nationality", 88 | famous_for="Celebrate Yourself Here" 89 | ) 90 | 91 | # add each instance of our programmers to our session 92 | # session.add(ada_lovelace) 93 | # session.add(alan_turing) 94 | # session.add(grace_hopper) 95 | # session.add(margaret_hamilton) 96 | # session.add(bill_gates) 97 | # session.add(tim_berners_lee) 98 | # session.add(your_name) 99 | 100 | 101 | # updating a single record 102 | # programmer = session.query(Programmer).filter_by(id=7).first() 103 | # programmer.famous_for = "World President" 104 | 105 | # commit our session to the database 106 | # session.commit() 107 | 108 | 109 | # updating multiple records 110 | # people = session.query(Programmer) 111 | # for person in people: 112 | # if person.gender == "F": 113 | # person.gender = "Female" 114 | # elif person.gender == "M": 115 | # person.gender = "Male" 116 | # else: 117 | # print("Gender not defined") 118 | # session.commit() 119 | 120 | 121 | # deleting a single record 122 | # fname = input("Enter a first name: ") 123 | # lname = input("Enter a last name: ") 124 | # programmer = session.query(Programmer).filter_by(first_name=fname, last_name=lname).first() 125 | # defensive programming 126 | # if programmer is not None: 127 | # print("Programmer Found: ", programmer.first_name + " " + programmer.last_name) 128 | # confirmation = input("Are you sure you want to delete this record? (y/n) ") 129 | # if confirmation.lower() == "y": 130 | # session.delete(programmer) 131 | # session.commit() 132 | # print("Programmer has been deleted") 133 | # else: 134 | # print("Programmer not deleted") 135 | # else: 136 | # print("No records found") 137 | 138 | 139 | # delete multiple/all records 140 | # programmers = session.query(Programmer) 141 | # for programmer in programmers: 142 | # session.delete(programmer) 143 | # session.commit() 144 | 145 | 146 | # query the database to find all Programmers 147 | programmers = session.query(Programmer) 148 | for programmer in programmers: 149 | print( 150 | programmer.id, 151 | programmer.first_name + " " + programmer.last_name, 152 | programmer.gender, 153 | programmer.nationality, 154 | programmer.famous_for, 155 | sep=" | " 156 | ) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DBMS lessons - source code 2 | 3 | ### [Lesson 01 - Installing the Chinook Database](https://github.com/Code-Institute-Solutions/postgresql-and-python/tree/main/01_installing_the_chinook_database) 4 | 5 | ### [Lesson 02 - PostgreSQL from the Command Line](https://github.com/Code-Institute-Solutions/postgresql-and-python/tree/main/02_postgresql_from_the_command_line) 6 | 7 | ### [Lesson 03 - Installing the Libraries and Setting Up](https://github.com/Code-Institute-Solutions/postgresql-and-python/tree/main/03_installing_the_libraries_and_setting_up) 8 | 9 | ### [Lesson 04 - Introducing an ORM](https://github.com/Code-Institute-Solutions/postgresql-and-python/tree/main/04_introducing_an_orm) 10 | 11 | ### [Lesson 05 - Running Basic Queries](https://github.com/Code-Institute-Solutions/postgresql-and-python/tree/main/05_running_basic_queries) 12 | 13 | ### [Lesson 06 - Introducing Class-Based Models](https://github.com/Code-Institute-Solutions/postgresql-and-python/tree/main/06_introducing_class_based_models) 14 | 15 | ### [Lesson 07 - CodeAlong: Create and Read](https://github.com/Code-Institute-Solutions/postgresql-and-python/tree/main/07_codealong_create_and_read) 16 | 17 | ### [Lesson 08 - CodeAlong: Update and Delete](https://github.com/Code-Institute-Solutions/postgresql-and-python/tree/main/08_codealong_update_and_delete) 18 | --------------------------------------------------------------------------------