From cc33aa600ce534f50cc64bd519cddc49772c4feb Mon Sep 17 00:00:00 2001 From: Jeremy Garcia Date: Sat, 19 Aug 2023 22:57:05 -0400 Subject: [PATCH] complete lab --- lib/debug.py | 4 +- lib/freebies.db | Bin 20480 -> 81920 bytes lib/freebies.db-journal | Bin 0 -> 4616 bytes ...51_add_print_details_method_to_freebie_.py | 28 ++++++++ .../de2c8c31ab7f_fixed_back_populates.py | 28 ++++++++ .../e256848f0940_add_freebie_model.py | 37 +++++++++++ lib/models.py | 62 +++++++++++++++++- lib/seed.py | 43 +++++++++++- 8 files changed, 197 insertions(+), 5 deletions(-) create mode 100644 lib/freebies.db-journal create mode 100644 lib/migrations/versions/40e2319e8a51_add_print_details_method_to_freebie_.py create mode 100644 lib/migrations/versions/de2c8c31ab7f_fixed_back_populates.py create mode 100644 lib/migrations/versions/e256848f0940_add_freebie_model.py diff --git a/lib/debug.py b/lib/debug.py index 4f922eb69..c7fb2bdeb 100644 --- a/lib/debug.py +++ b/lib/debug.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker -from models import Company, Dev +from models import Company, Dev, Freebie, session if __name__ == '__main__': - engine = create_engine('sqlite:///freebies.db') import ipdb; ipdb.set_trace() diff --git a/lib/freebies.db b/lib/freebies.db index 12beb1c963e832db481e7a7493e3029e691ac4dc..65684d557ff47094a7189358aca0761fe22f5b48 100644 GIT binary patch literal 81920 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 literal 0 HcmV?d00001 diff --git a/lib/migrations/versions/40e2319e8a51_add_print_details_method_to_freebie_.py b/lib/migrations/versions/40e2319e8a51_add_print_details_method_to_freebie_.py new file mode 100644 index 000000000..2a1004fca --- /dev/null +++ b/lib/migrations/versions/40e2319e8a51_add_print_details_method_to_freebie_.py @@ -0,0 +1,28 @@ +"""Add print_details Method to Freebie Model + +Revision ID: 40e2319e8a51 +Revises: de2c8c31ab7f +Create Date: 2023-08-19 17:19:54.653554 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '40e2319e8a51' +down_revision = 'de2c8c31ab7f' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### diff --git a/lib/migrations/versions/de2c8c31ab7f_fixed_back_populates.py b/lib/migrations/versions/de2c8c31ab7f_fixed_back_populates.py new file mode 100644 index 000000000..ec4ef64c6 --- /dev/null +++ b/lib/migrations/versions/de2c8c31ab7f_fixed_back_populates.py @@ -0,0 +1,28 @@ +"""fixed back_populates + +Revision ID: de2c8c31ab7f +Revises: e256848f0940 +Create Date: 2023-08-19 16:44:28.392322 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'de2c8c31ab7f' +down_revision = 'e256848f0940' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### diff --git a/lib/migrations/versions/e256848f0940_add_freebie_model.py b/lib/migrations/versions/e256848f0940_add_freebie_model.py new file mode 100644 index 000000000..96dc270ae --- /dev/null +++ b/lib/migrations/versions/e256848f0940_add_freebie_model.py @@ -0,0 +1,37 @@ +"""Add Freebie Model + +Revision ID: e256848f0940 +Revises: 5f72c58bf48c +Create Date: 2023-08-19 16:23:11.154674 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'e256848f0940' +down_revision = '5f72c58bf48c' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + 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') + # ### end Alembic commands ### diff --git a/lib/models.py b/lib/models.py index 2681bee5a..b35a9da7d 100644 --- a/lib/models.py +++ b/lib/models.py @@ -1,6 +1,7 @@ -from sqlalchemy import ForeignKey, Column, Integer, String, MetaData -from sqlalchemy.orm import relationship, backref +from sqlalchemy import ForeignKey, Column, Integer, String, MetaData, create_engine, desc +from sqlalchemy.orm import relationship, sessionmaker from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.ext.associationproxy import association_proxy convention = { "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s", @@ -9,6 +10,10 @@ Base = declarative_base(metadata=metadata) +engine = create_engine('sqlite:///freebies.db') +Session = sessionmaker(bind=engine) +session = Session() + class Company(Base): __tablename__ = 'companies' @@ -16,8 +21,22 @@ class Company(Base): name = Column(String()) founding_year = Column(Integer()) + freebies = relationship('Freebie', back_populates='company', cascade='all, delete-orphan') + devs = association_proxy('freebies', 'dev', creator=lambda de: Freebie(dev=de)) + def __repr__(self): return f'' + + def give_freebie(self, dev, item_name, value): + new_freebie = Freebie(item_name=item_name, value=value, company=self, dev=dev) + session.add(new_freebie) + session.commit() + return new_freebie + + @classmethod + def oldest_company(cls): + oldest_co = session.query(cls).order_by(cls.founding_year).first() + return oldest_co class Dev(Base): __tablename__ = 'devs' @@ -25,5 +44,44 @@ class Dev(Base): id = Column(Integer(), primary_key=True) name= Column(String()) + freebies = relationship('Freebie', back_populates='dev', cascade='all, delete-orphan') + companies = association_proxy('freebies', 'company', creator=lambda co: Freebie(company=co)) + def __repr__(self): return f'' + + def received_one(self, item_name): + for fb in [freebie.item_name for freebie in self.freebies]: + if fb == item_name: + return True + return False + + def give_away(self, dev, freebie): + if freebie in self.freebies: + session.query(Freebie).filter(Freebie.id == freebie.id).update({Freebie.dev_id: dev.id}) + print(f'{self.name} gave away their {freebie.item_name} to {dev.name}.') + else: + print(f'{self.name} does not have a {freebie.item_name}.') + + +class Freebie(Base): + __tablename__ = 'freebies' + + id = Column(Integer(), primary_key=True) + item_name = Column(String()) + value = Column(Integer()) + + company_id = Column(Integer(), ForeignKey('companies.id')) + dev_id = Column(Integer(), ForeignKey('devs.id')) + + company = relationship('Company', back_populates='freebies') + dev = relationship('Dev', 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}' + + +#import ipdb; ipdb.set_trace() diff --git a/lib/seed.py b/lib/seed.py index b16becbbb..6a9a4062f 100644 --- a/lib/seed.py +++ b/lib/seed.py @@ -1,3 +1,44 @@ #!/usr/bin/env python3 -# Script goes here! +from random import choice as rc +import random + +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker + +from models import Company, Dev, Freebie + +engine = create_engine('sqlite:///freebies.db') +Session = sessionmaker(bind=engine) +session = Session() + +co_names = ['Facebook', 'Instagram', 'MySpace', 'Reddit', 'Neighborly', 'Walmart', 'Target', 'CostCo'] +dev_names = ['Jake', 'Jerry', 'Jan', 'Mike', 'Bob', 'Chris', 'Jon', 'Sarah', 'Beth', 'Ben', 'Jill', 'Jake', 'Jennifer', 'Sam', 'Samantha', 'Eduardo', 'Amber', 'Melonie', 'Daryl', 'Chloe'] +fb_names = ['Shirt', 'Pants', 'Scarf', 'Socks', 'Face Mask', 'Tie', 'Jacket', 'Earings', 'Ring', 'Watch', 'Backpack', 'Draw String Bag', 'Umbrella'] + +def create_records(): + companies = [Company(name=co_names[i], founding_year=random.randint(1800,2000)) for i in range(8)] + devs = [Dev(name=rc(dev_names)) for i in range(500)] + freebies = [Freebie(item_name=rc(fb_names), value=random.randint(0, 100)) for i in range(2000)] + session.add_all(companies + devs + freebies) + session.commit() + return companies, devs, freebies + +def delete_records(): + session.query(Company).delete() + session.query(Dev).delete() + session.query(Freebie).delete() + session.commit() + +def relate_one_to_many(companies, devs, freebies): + for freebie in freebies: + freebie.company = rc(companies) + freebie.dev = rc(devs) + session.add_all(freebies) + session.commit() + return companies, devs, freebies + +if __name__ == '__main__': + delete_records() + companies, devs, freebies = create_records() + companies, devs, freebies = relate_one_to_many(companies, devs, freebies)