diff --git a/lib/debug.py b/lib/debug.py index 4f922eb69..cd2732061 100644 --- a/lib/debug.py +++ b/lib/debug.py @@ -1,9 +1,29 @@ #!/usr/bin/env python3 - +from models import Company, Dev, Freebie from sqlalchemy import create_engine - -from models import Company, Dev +from sqlalchemy.orm import sessionmaker if __name__ == '__main__': engine = create_engine('sqlite:///freebies.db') + Session = sessionmaker(bind=engine) + session = Session() + + # Retrieve objects + dev = session.query(Dev).filter_by(name="Alice").first() + company = session.query(Company).filter_by(name="Google").first() + + # Test received_one() + print(dev.received_one("Laptop")) # output: True + print(dev.received_one("Tablet")) # output: False + + # Test give_away() + freebie = session.query(Freebie).filter_by(item_name="Laptop").first() + dev.give_away(session.query(Dev).filter_by(name="Bob").first(), freebie) + session.commit() + + # Test print_details() + print(freebie.print_details()) # Should show Bob owns a Laptop from Google + + # Test oldest_company() + print(Company.oldest_company(session)) #output: microsoft import ipdb; ipdb.set_trace() diff --git a/lib/freebies.db b/lib/freebies.db index 12beb1c96..4dd4314b6 100644 Binary files a/lib/freebies.db and b/lib/freebies.db differ diff --git a/lib/migrations/versions/5164d437f2c6_create_freebie_models.py b/lib/migrations/versions/5164d437f2c6_create_freebie_models.py new file mode 100644 index 000000000..ae14fb9ab --- /dev/null +++ b/lib/migrations/versions/5164d437f2c6_create_freebie_models.py @@ -0,0 +1,45 @@ +"""create freebie models + +Revision ID: 5164d437f2c6 +Revises: 5f72c58bf48c +Create Date: 2025-03-03 21:30:04.450269 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '5164d437f2c6' +down_revision = '5f72c58bf48c' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('company_dev', + sa.Column('company_id', sa.Integer(), nullable=False), + sa.Column('dev_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['company_id'], ['companies.id'], name=op.f('fk_company_dev_company_id_companies')), + sa.ForeignKeyConstraint(['dev_id'], ['devs.id'], name=op.f('fk_company_dev_dev_id_devs')), + sa.PrimaryKeyConstraint('company_id', 'dev_id') + ) + op.create_table('freebies', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('item_name', sa.String(), nullable=True), + sa.Column('value', sa.Integer(), nullable=True), + sa.Column('company_id', sa.Integer(), nullable=True), + sa.Column('dev_id', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['company_id'], ['companies.id'], name=op.f('fk_freebies_company_id_companies')), + sa.ForeignKeyConstraint(['dev_id'], ['devs.id'], name=op.f('fk_freebies_dev_id_devs')), + sa.PrimaryKeyConstraint('id') + ) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('freebies') + op.drop_table('company_dev') + # ### end Alembic commands ### diff --git a/lib/models.py b/lib/models.py index 2681bee5a..096f3bc22 100644 --- a/lib/models.py +++ b/lib/models.py @@ -1,7 +1,8 @@ -from sqlalchemy import ForeignKey, Column, Integer, String, MetaData +from sqlalchemy import ForeignKey, Column, Integer, String, MetaData, Table from sqlalchemy.orm import relationship, backref from sqlalchemy.ext.declarative import declarative_base +# Naming convention for migrations convention = { "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s", } @@ -9,21 +10,71 @@ Base = declarative_base(metadata=metadata) +# Association Table +company_dev = Table( + 'company_dev', + Base.metadata, + Column('company_id', ForeignKey('companies.id'), primary_key=True), + Column('dev_id', ForeignKey('devs.id'), primary_key=True), + extend_existing=True, +) + class Company(Base): __tablename__ = 'companies' id = Column(Integer(), primary_key=True) - name = Column(String()) - founding_year = Column(Integer()) + name = Column(String(), nullable=False) + founding_year = Column(Integer(), nullable=False) + + freebies = relationship("Freebie", backref="company") + devs = relationship("Dev", secondary=company_dev, back_populates="companies") def __repr__(self): return f'' + def give_freebie(self, dev, item_name, value): + #Creates a new Freebie instance associated with this company and the given dev. + freebie = Freebie(item_name=item_name, value=value, company=self, dev=dev) + return freebie + + @classmethod + def oldest_company(cls, session): + #Returns the Company instance with the earliest founding year. + 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(), nullable=False) + + freebies = relationship("Freebie", backref="dev") + companies = relationship("Company", secondary=company_dev, back_populates="devs") def __repr__(self): return f'' + + def received_one(self, item_name): + #Returns True if the dev has received a Freebie with the given item_name. + return any(freebie.item_name == item_name for freebie in self.freebies) + + def give_away(self, dev, freebie): + #Transfers a freebie to another dev if the freebie belongs to the current dev. + if freebie in self.freebies: + freebie.dev = dev + +class Freebie(Base): + __tablename__ = "freebies" + + id = Column(Integer(), primary_key=True) + item_name = Column(String(), nullable=False) + value = Column(Integer(), nullable=False) + company_id = Column(Integer(), ForeignKey("companies.id")) + dev_id = Column(Integer(), ForeignKey("devs.id")) + + def __repr__(self): + return f"" + + def print_details(self): + #Returns a formatted string with freebie details. + return f"{self.dev.name} owns a {self.item_name} from {self.company.name}" diff --git a/lib/seed.py b/lib/seed.py index b16becbbb..a4fac1696 100644 --- a/lib/seed.py +++ b/lib/seed.py @@ -1,3 +1,29 @@ #!/usr/bin/env python3 # Script goes here! +from models import Base, Company, Dev, Freebie +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker + + +engine = create_engine('sqlite:///freebies.db') +Base.metadata.create_all(engine) + +Session = sessionmaker(bind=engine) +session = Session() + +# Create some Companies +google = Company(name="Google", founding_year=1998) +microsoft = Company(name="Microsoft", founding_year=1975) + +# Create some Devs +alice = Dev(name="Alice") +bob = Dev(name="Bob") + +# Create some Freebies +freebie1 = Freebie(item_name="Laptop", value=1000, company=google, dev=alice) +freebie2 = Freebie(item_name="Headphones", value=200, company=microsoft, dev=bob) +freebie3 = Freebie(item_name="Smartwatch", value=300, company=google, dev=alice) + +session.add_all([google, microsoft, alice, bob, freebie1, freebie2, freebie3]) +session.commit() \ No newline at end of file