order, group, and join tables

use SQLAlchemy
This commit is contained in:
slashtechno 2024-06-04 11:18:04 -05:00
parent 0eaa8296a0
commit 822d67675b
Signed by: slashtechno
GPG Key ID: 8EC1D9D9286C2B17
3 changed files with 104 additions and 6 deletions

View File

@ -5,7 +5,7 @@
groups = ["default"] groups = ["default"]
strategy = ["cross_platform", "inherit_metadata"] strategy = ["cross_platform", "inherit_metadata"]
lock_version = "4.4.1" lock_version = "4.4.1"
content_hash = "sha256:2be337f3deba8cffea31cdbd43024c3db7bed53a688b484b32a3b92c27c530cf" content_hash = "sha256:3c4bf81bc71a0e1f56d0f71f725ba2668ff4346e236ae89f946e0ee388a47e83"
[[package]] [[package]]
name = "asttokens" name = "asttokens"
@ -42,6 +42,26 @@ files = [
{file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"}, {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"},
] ]
[[package]]
name = "greenlet"
version = "3.0.3"
requires_python = ">=3.7"
summary = "Lightweight in-process concurrent programming"
groups = ["default"]
marker = "platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\""
files = [
{file = "greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be"},
{file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e"},
{file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676"},
{file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc"},
{file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230"},
{file = "greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf"},
{file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305"},
{file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6"},
{file = "greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2"},
{file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"},
]
[[package]] [[package]]
name = "icecream" name = "icecream"
version = "2.1.3" version = "2.1.3"
@ -112,3 +132,37 @@ files = [
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
] ]
[[package]]
name = "sqlalchemy"
version = "2.0.30"
requires_python = ">=3.7"
summary = "Database Abstraction Library"
groups = ["default"]
dependencies = [
"greenlet!=0.4.17; platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\"",
"typing-extensions>=4.6.0",
]
files = [
{file = "SQLAlchemy-2.0.30-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5a79d65395ac5e6b0c2890935bad892eabb911c4aa8e8015067ddb37eea3d56c"},
{file = "SQLAlchemy-2.0.30-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9a5baf9267b752390252889f0c802ea13b52dfee5e369527da229189b8bd592e"},
{file = "SQLAlchemy-2.0.30-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cb5a646930c5123f8461f6468901573f334c2c63c795b9af350063a736d0134"},
{file = "SQLAlchemy-2.0.30-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:296230899df0b77dec4eb799bcea6fbe39a43707ce7bb166519c97b583cfcab3"},
{file = "SQLAlchemy-2.0.30-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c62d401223f468eb4da32627bffc0c78ed516b03bb8a34a58be54d618b74d472"},
{file = "SQLAlchemy-2.0.30-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3b69e934f0f2b677ec111b4d83f92dc1a3210a779f69bf905273192cf4ed433e"},
{file = "SQLAlchemy-2.0.30-cp312-cp312-win32.whl", hash = "sha256:77d2edb1f54aff37e3318f611637171e8ec71472f1fdc7348b41dcb226f93d90"},
{file = "SQLAlchemy-2.0.30-cp312-cp312-win_amd64.whl", hash = "sha256:b6c7ec2b1f4969fc19b65b7059ed00497e25f54069407a8701091beb69e591a5"},
{file = "SQLAlchemy-2.0.30-py3-none-any.whl", hash = "sha256:7108d569d3990c71e26a42f60474b4c02c8586c4681af5fd67e51a044fdea86a"},
{file = "SQLAlchemy-2.0.30.tar.gz", hash = "sha256:2b1708916730f4830bc69d6f49d37f7698b5bd7530aca7f04f785f8849e95255"},
]
[[package]]
name = "typing-extensions"
version = "4.12.1"
requires_python = ">=3.8"
summary = "Backported and Experimental Type Hints for Python 3.8+"
groups = ["default"]
files = [
{file = "typing_extensions-4.12.1-py3-none-any.whl", hash = "sha256:6024b58b69089e5a89c347397254e35f1bf02a907728ec7fee9bf0fe837d203a"},
{file = "typing_extensions-4.12.1.tar.gz", hash = "sha256:915f5e35ff76f56588223f15fdd5938f9a1cf9195c0de25130c627e4d597f6d1"},
]

View File

@ -9,6 +9,7 @@ dependencies = [
"psycopg2-binary>=2.9.9", "psycopg2-binary>=2.9.9",
"python-dotenv>=1.0.1", "python-dotenv>=1.0.1",
"icecream>=2.1.3", "icecream>=2.1.3",
"SQLAlchemy>=2.0.30",
] ]
requires-python = ">=3.12" requires-python = ">=3.12"
readme = "README.md" readme = "README.md"
@ -19,7 +20,7 @@ requires = ["pdm-backend"]
build-backend = "pdm.backend" build-backend = "pdm.backend"
[project.scripts] [project.scripts]
hello-postgres = "hello_postgres.__main__:main" datacamp-postgres-tutorial = "hello_postgres.datacamp_tutorial:main"
[tool.pdm] [tool.pdm]

View File

@ -1,6 +1,5 @@
# https://www.freecodecamp.org/news/postgresql-in-python/
# https://www.datacamp.com/tutorial/tutorial-postgresql-python # https://www.datacamp.com/tutorial/tutorial-postgresql-python
# docker compose down && docker compose up -d && hello-postgres # docker compose down && docker compose up -d && datacamp-postgres-tutorial
import psycopg2 import psycopg2
import dotenv import dotenv
import os import os
@ -8,6 +7,7 @@ import os
def main(): def main():
dotenv.load_dotenv()
print("Connecting to the PostgreSQL database...") print("Connecting to the PostgreSQL database...")
conn = connect() conn = connect()
cursor = conn.cursor() cursor = conn.cursor()
@ -45,13 +45,56 @@ def main():
print("Deleting \"Introduction to Statistics in R\"...") print("Deleting \"Introduction to Statistics in R\"...")
cursor.execute("DELETE from datacamp_courses WHERE course_name = 'Introduction to Statistics in R';") cursor.execute("DELETE from datacamp_courses WHERE course_name = 'Introduction to Statistics in R';")
conn.commit() conn.commit()
print("Sorting table by instructor...")
cursor.execute('SELECT * FROM datacamp_courses ORDER BY course_instructor')
rows = cursor.fetchall()
for row in rows:
print(row)
print("Fetching the number of courses each instructor teaches...")
cursor.execute('SELECT course_instructor, COUNT(*) FROM datacamp_courses GROUP BY course_instructor')
for row in cursor.fetchall():
print(row)
print("Creating the new table for language rankings...")
# https://www.w3schools.com/sql/sql_primarykey.ASP
cursor.execute("""
CREATE TABLE programming_languages (
language_id INT PRIMARY KEY,
language_name TEXT NOT NULL,
course_number INT NOT NULL,
tiobe_ranking INT NOT NULL
)
""")
cursor.execute("""
INSERT INTO programming_languages (language_id, language_name, course_number, tiobe_ranking)
VALUES
(1, 'SQL', 31, 8),
(2, 'Python', 157, 1),
(3, 'R', 132, 16),
(4, 'Julia', 2, 33),
(5, 'Scala', 1, 38)
""")
conn.commit()
# datacamp: "We will use an INNER JOIN to get only the information of the programming languages that appear in the datacamp_course table. "
print("Getting courses, their instructors, the topic, and the tiobe ranking of the language...")
cursor.execute("""SELECT course_name, course_instructor, topic, tiobe_ranking
FROM datacamp_courses
INNER JOIN programming_languages
ON datacamp_courses.topic = programming_languages.language_name""")
for row in cursor.fetchall():
print(row)
cursor.close() cursor.close()
conn.close() conn.close()
# cursor.execute("SELECT * FROM DB_table WHERE id = 1") print("Now using SQLAlchemy to interact with the database...")
import sqlalchemy
engine = sqlalchemy.create_engine(f"postgresql://{os.getenv('POSTGRES_USER')}:{os.getenv('POSTGRES_PASSWORD')}@{os.getenv('DB_HOST')}:{os.getenv('DB_PORT')}/{os.getenv('POSTGRES_DB')}")
conn = engine.connect()
print("Fetching all the available rows...")
output = conn.execute(sqlalchemy.text("SELECT * FROM datacamp_courses"))
print(output.fetchall())
conn.close()
def connect(): def connect():
dotenv.load_dotenv()
conn = psycopg2.connect( conn = psycopg2.connect(
database=os.getenv('POSTGRES_DB'), database=os.getenv('POSTGRES_DB'),
host=os.getenv('DB_HOST'), host=os.getenv('DB_HOST'),