From 82123c929c3f419aaae24d461e91cb509cbee0dc Mon Sep 17 00:00:00 2001 From: Bismark Date: Wed, 28 May 2025 12:18:30 +0300 Subject: [PATCH] freebies --- lib/alembic.ini => alembic.ini | 0 lib/__init__.py | 0 lib/database.py | 3 + lib/debug.py | 53 ++++++++++++++++-- lib/freebies.db | Bin 20480 -> 24576 bytes .../versions/7a71dbf71c64_create_db.py | 24 -------- lib/models.py | 52 ++++++++++++++++- lib/seed.py | 3 - {lib/migrations => migrations}/README | 0 {lib/migrations => migrations}/env.py | 12 +++- {lib/migrations => migrations}/script.py.mako | 0 .../c87044fda2e0_create_freebies_table.py | 31 ++++++++++ .../f576b461a0be_add_freebies_table.py | 12 ++-- seed.py | 32 +++++++++++ your_database.db | 0 15 files changed, 179 insertions(+), 43 deletions(-) rename lib/alembic.ini => alembic.ini (100%) create mode 100644 lib/__init__.py create mode 100644 lib/database.py delete mode 100644 lib/migrations/versions/7a71dbf71c64_create_db.py delete mode 100644 lib/seed.py rename {lib/migrations => migrations}/README (100%) rename {lib/migrations => migrations}/env.py (90%) rename {lib/migrations => migrations}/script.py.mako (100%) create mode 100644 migrations/versions/c87044fda2e0_create_freebies_table.py rename lib/migrations/versions/5f72c58bf48c_create_companies_devs.py => migrations/versions/f576b461a0be_add_freebies_table.py (83%) create mode 100644 seed.py create mode 100644 your_database.db diff --git a/lib/alembic.ini b/alembic.ini similarity index 100% rename from lib/alembic.ini rename to alembic.ini diff --git a/lib/__init__.py b/lib/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/lib/database.py b/lib/database.py new file mode 100644 index 000000000..72d234b91 --- /dev/null +++ b/lib/database.py @@ -0,0 +1,3 @@ +from sqlalchemy import create_engine + +engine = create_engine('sqlite:///lib/freebies.db') diff --git a/lib/debug.py b/lib/debug.py index 4f922eb69..a930c2c85 100644 --- a/lib/debug.py +++ b/lib/debug.py @@ -1,9 +1,50 @@ -#!/usr/bin/env python3 +from lib.models import Company, Dev, Freebie, Base +from sqlalchemy.orm import sessionmaker +from lib.database import engine -from sqlalchemy import create_engine +Base.metadata.create_all(engine) +Session = sessionmaker(bind=engine) +session = Session() -from models import Company, Dev +oldest = Company.oldest_company(session) +print("Oldest company:", oldest.name if oldest else "None") -if __name__ == '__main__': - engine = create_engine('sqlite:///freebies.db') - import ipdb; ipdb.set_trace() +# Create tables (run once or during setup) +Base.metadata.create_all(engine) + +# Create a session +Session = sessionmaker(bind=engine) +session = Session() + +# Add seed data if needed +# Run this only once or protect with `if not session.query(...).first():` +# Example: +# google = Company(name="Google", founding_year=1998) +# alice = Dev(name="Alice") +# session.add_all([google, alice]) +# session.commit() + +# Test oldest company +print("Oldest company:", Company.oldest_company(session).name) + +# Test dev received_one +dev = session.query(Dev).filter_by(name="Alice").first() +print("Alice received T-shirt?", dev.received_one("T-shirt")) + +# Test print_details +freebie = session.query(Freebie).first() +print(freebie.print_details()) + +# Test give_freebie +company = session.query(Company).filter_by(name="Google").first() +new_freebie = company.give_freebie(dev, "Cap", 15) +session.add(new_freebie) +session.commit() + +print(new_freebie.print_details()) + +# Test give_away +bob = session.query(Dev).filter_by(name="Bob").first() +dev.give_away(bob, new_freebie) +session.commit() +print(new_freebie.print_details()) # Should now show Bob as the owner diff --git a/lib/freebies.db b/lib/freebies.db index 12beb1c963e832db481e7a7493e3029e691ac4dc..302ef7ac9876d014d8f81d435a9cee9eaeb7671b 100644 GIT binary patch delta 583 zcmZozz}Rqrae}m<7y|dd){X$&bT~TFHQp@5qQ?N=U=jRqA z=2ha74hZt}bqtDB@OF(<(5TN$(F9rK?C%#G666T9Ng*ve9_H+Lh%F$hSi#Ld$ko%` z52Q~6BCe?r#X uPDYRX{FKa8BPIbRHU?=%M#kWh%;fCUB333QK1PrTCufLmaYklQi3kAZHlfu3 delta 87 zcmZoTz}T>Wae}lUD+2=q2*UvLL>*&MRtCLzSzi7h3@m(74E((OJNfGQq&5o*EaTlQ Y#rH~)i9rC!xz9gwf;1a1NF$sJ0HVYZR{#J2 diff --git a/lib/migrations/versions/7a71dbf71c64_create_db.py b/lib/migrations/versions/7a71dbf71c64_create_db.py deleted file mode 100644 index 23e0a655b..000000000 --- a/lib/migrations/versions/7a71dbf71c64_create_db.py +++ /dev/null @@ -1,24 +0,0 @@ -"""create db - -Revision ID: 7a71dbf71c64 -Revises: -Create Date: 2023-03-15 15:05:55.516631 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = '7a71dbf71c64' -down_revision = None -branch_labels = None -depends_on = None - - -def upgrade() -> None: - pass - - -def downgrade() -> None: - pass diff --git a/lib/models.py b/lib/models.py index 2681bee5a..45c340e1d 100644 --- a/lib/models.py +++ b/lib/models.py @@ -16,14 +16,64 @@ class Company(Base): name = Column(String()) founding_year = Column(Integer()) + freebies = relationship('Freebie', back_populates='company') + def __repr__(self): return f'' + @property + def devs(self): + # Return unique devs who got freebies from this company + return list({freebie.dev for freebie in self.freebies}) + + def give_freebie(self, dev, item_name, value): + freebie = Freebie(item_name=item_name, value=value, dev=dev, company=self) + return freebie + + @classmethod + def oldest_company(cls, session): + return session.query(cls).order_by(cls.founding_year).first() + + class Dev(Base): __tablename__ = 'devs' id = Column(Integer(), primary_key=True) - name= Column(String()) + name = Column(String()) + + freebies = relationship('Freebie', back_populates='dev') def __repr__(self): return f'' + + @property + def companies(self): + # Return unique companies from which this dev received freebies + return list({freebie.company for freebie in self.freebies}) + + def received_one(self, item_name): + return any(freebie.item_name == item_name for freebie in self.freebies) + + def give_away(self, new_dev, freebie): + if freebie.dev == self: + freebie.dev = new_dev + + +class Freebie(Base): + __tablename__ = 'freebies' + + id = Column(Integer(), primary_key=True) + item_name = Column(String(), nullable=False) + value = Column(Integer(), nullable=False) + + dev_id = Column(Integer(), ForeignKey('devs.id'), nullable=False) + company_id = Column(Integer(), ForeignKey('companies.id'), nullable=False) + + dev = relationship('Dev', back_populates='freebies') + company = relationship('Company', back_populates='freebies') + + def __repr__(self): + return f'' + + def print_details(self): + return f"{self.dev.name} owns a {self.item_name} from {self.company.name}" diff --git a/lib/seed.py b/lib/seed.py deleted file mode 100644 index b16becbbb..000000000 --- a/lib/seed.py +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env python3 - -# Script goes here! diff --git a/lib/migrations/README b/migrations/README similarity index 100% rename from lib/migrations/README rename to migrations/README diff --git a/lib/migrations/env.py b/migrations/env.py similarity index 90% rename from lib/migrations/env.py rename to migrations/env.py index c7aab9656..2fc4d886a 100644 --- a/lib/migrations/env.py +++ b/migrations/env.py @@ -5,6 +5,13 @@ from alembic import context +import sys +import os +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'lib'))) + +from lib.models import Base # adjust if your Base is named differently +target_metadata = Base.metadata + # this is the Alembic Config object, which provides # access to the values within the .ini file in use. config = context.config @@ -18,8 +25,7 @@ # for 'autogenerate' support # from myapp import mymodel # target_metadata = mymodel.Base.metadata -from models import Base -target_metadata = Base.metadata +# target_metadata = None # other values from the config, defined by the needs of env.py, # can be acquired: @@ -66,7 +72,7 @@ def run_migrations_online() -> None: with connectable.connect() as connection: context.configure( - connection=connection, target_metadata=target_metadata, render_as_batch=True, + connection=connection, target_metadata=target_metadata ) with context.begin_transaction(): diff --git a/lib/migrations/script.py.mako b/migrations/script.py.mako similarity index 100% rename from lib/migrations/script.py.mako rename to migrations/script.py.mako diff --git a/migrations/versions/c87044fda2e0_create_freebies_table.py b/migrations/versions/c87044fda2e0_create_freebies_table.py new file mode 100644 index 000000000..43800522e --- /dev/null +++ b/migrations/versions/c87044fda2e0_create_freebies_table.py @@ -0,0 +1,31 @@ +"""create freebies table + +Revision ID: c87044fda2e0 +Revises: f576b461a0be +Create Date: 2025-05-28 11:25:24.019367 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'c87044fda2e0' +down_revision = 'f576b461a0be' +branch_labels = None +depends_on = None + + +def upgrade(): + op.create_table( + 'freebies', + sa.Column('id', sa.Integer, primary_key=True), + sa.Column('item_name', sa.String, nullable=False), + sa.Column('value', sa.Integer, nullable=False), + sa.Column('dev_id', sa.Integer, sa.ForeignKey('devs.id'), nullable=False), + sa.Column('company_id', sa.Integer, sa.ForeignKey('companies.id'), nullable=False) + ) + + +def downgrade(): + op.drop_table('freebies') \ No newline at end of file diff --git a/lib/migrations/versions/5f72c58bf48c_create_companies_devs.py b/migrations/versions/f576b461a0be_add_freebies_table.py similarity index 83% rename from lib/migrations/versions/5f72c58bf48c_create_companies_devs.py rename to migrations/versions/f576b461a0be_add_freebies_table.py index c191bb2f9..e0e294ab4 100644 --- a/lib/migrations/versions/5f72c58bf48c_create_companies_devs.py +++ b/migrations/versions/f576b461a0be_add_freebies_table.py @@ -1,8 +1,8 @@ -"""create companies, devs +"""Add freebies table -Revision ID: 5f72c58bf48c -Revises: 7a71dbf71c64 -Create Date: 2023-03-15 15:06:20.944586 +Revision ID: f576b461a0be +Revises: +Create Date: 2025-05-28 11:17:56.423307 """ from alembic import op @@ -10,8 +10,8 @@ # revision identifiers, used by Alembic. -revision = '5f72c58bf48c' -down_revision = '7a71dbf71c64' +revision = 'f576b461a0be' +down_revision = None branch_labels = None depends_on = None diff --git a/seed.py b/seed.py new file mode 100644 index 000000000..c433c0ca6 --- /dev/null +++ b/seed.py @@ -0,0 +1,32 @@ +from lib.models import Base, Company, Dev, Freebie +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker + +engine = create_engine('sqlite:///lib/freebies.db') +Session = sessionmaker(bind=engine) +session = Session() + +# Clear tables (optional) +Base.metadata.drop_all(engine) +Base.metadata.create_all(engine) + +# Create sample companies +c1 = Company(name="Moringa", founding_year=1998) +c2 = Company(name="Citizen", founding_year=1975) + +# Create sample devs +d1 = Dev(name="Keith") +d2 = Dev(name="Emily") + +session.add_all([c1, c2, d1, d2]) +session.commit() + +# Create freebies +f1 = Freebie(item_name="T-shirt", value=20, dev=d1, company=c1) +f2 = Freebie(item_name="Sticker", value=5, dev=d2, company=c2) +f3 = Freebie(item_name="Hoodie", value=50, dev=d1, company=c2) + +session.add_all([f1, f2, f3]) +session.commit() + +print("Seed data created!") diff --git a/your_database.db b/your_database.db new file mode 100644 index 000000000..e69de29bb