From b828e8e9736fe6550572e7a9f1951dd358bdaa00 Mon Sep 17 00:00:00 2001 From: Billy Eskein Date: Thu, 6 Mar 2025 07:46:26 +0300 Subject: [PATCH 1/2] Update lib/models.py --- lib/debug.py | 11 +++- lib/freebies.db | Bin 20480 -> 32768 bytes ...7e3d_add_freebie_and_dev_company_models.py | 45 ++++++++++++++ lib/models.py | 46 +++++++++++++- lib/seed.py | 56 +++++++++++++++++- 5 files changed, 152 insertions(+), 6 deletions(-) create mode 100644 lib/migrations/versions/853a93127e3d_add_freebie_and_dev_company_models.py diff --git a/lib/debug.py b/lib/debug.py index 4f922eb69..45ce58879 100644 --- a/lib/debug.py +++ b/lib/debug.py @@ -1,9 +1,16 @@ #!/usr/bin/env python3 from sqlalchemy import create_engine - -from models import Company, Dev +from sqlalchemy.orm import sessionmaker +from models import Base,Company, Dev,Freebie +from seed import seed_data if __name__ == '__main__': engine = create_engine('sqlite:///freebies.db') + Session = sessionmaker(bind= engine) + session = Session() + + #seed the database with the seed data + seed_data() + import ipdb; ipdb.set_trace() diff --git a/lib/freebies.db b/lib/freebies.db index 12beb1c963e832db481e7a7493e3029e691ac4dc..18369798bd3412ea34095b808e2246f4a94f8548 100644 GIT binary patch literal 32768 zcmeI5TWlL?6@bUriDS=ZGY1QdPi4f9yZ;knv2I z8Mk$KShdR{A@P7fD+CV+39(N|NFZ(kgoGA}i?kpf7K8+g1ggXfix3aX6P$m>PUC1R zv=2zDaz;(iasaGqRT}<=1naSMO1+adw3-ud;jlPc(5!#i*Z9y?H^pQ`*?dmF|+8 zg}Y=-t&a1R`CHrN-BJ#`Acx2MZQu5vC}_QfaLDSdQek6lo8Le7WWhKo6;=zS!gjt; zCa#z-{x1expZDRVQ?D!U(CMt<>bl1teK;T{Mn^rLY&f9#;xmgKC&3Qn9hW$FE_gz$ zgZ-1h-ZeEH3|%#ot*ANfcVXIL{C@_v(~9fZd!?HV1`}JO9zoTs?1A-h4a#tzHf+N= z=gOYI-cNO$iWR?@h{rt-$J=?a;JOvKm<1?{rxyMBdgqndLE6dw!>~_G3=Mf6GRMkU z=Fi^vJM5i_--FRZqoG$-{b;|*sM#)nr+72&5fc*=o<||a8>+GTfm+$W$4pB#^b4on z4$m%Jm8+t(ZQ_Cr6GNso7w=DBC}f`{)zcAq~ z83!ttP2~;_4BHm}6b<@?VJ~PgRm)lUvz~xo81WV~O@#$hH(^*oe4Y6HLe9HxG%VZD zC&?NNAnA_HRhUZPD}EdIarJp>a)aEPvY}hz?|Qsk*>c0yz{xe!XqwQ@XFGLB%XLHsG-|ED8{puDa8QTe&@9pyFURpn*HR;Y4Yc|jRddK9nxH~B63 z*Yc0$ughPOKPB7ppkPVPW>OpgwL z1Xi(=8Y!tTqfTQ<9uuUkO3z|SoW-;SG4;bOdn#CGMdkFi43kPx zIL$#NwW3zQj+>|zqj6LN-A!2rR@-U?N(}<2us+Er%xpnonSRRo*$mQU$0A^Rol#(H zk}`V$oASOeEQHG^kSkcY%5i9#+|8?*Rct`LPBkqSf*ada#H$iGcY#xGaok}C2T>6M zT?UsSs8!Vh149vAPl6FVkN^@u0!RP}AOR$R1dzb{jle)U zC``mWo}17%&g>f5p;c(wrJ3wdS3DIIMq-{&?!;6zvPR8{O4FI%o6yv(kvxT#YfUp2=KZ1mNyiOO!Bmf-Gn>}o`w8bWy}tg5pfIX%Kip369P}FN zivwccji4|Lx{BZ*g|28rPcKNJ#5k;We1qm?SP8xM#_@dmdN48OUdY#|#fXEU+60$^ ziP7_SkUOS&RI?Z6dwj|3EdZ?!{hSFs_+~ae=uM6|FhlJqTix+X+3Wq++#rA=Z_cJw z=zyP_4FvkG0x}4q)px$fj%a4WH~74ZqaE5EV4>2wm0eK8{$X&dHxyc?<^lAsyA9K+ z+1Vs zmp!}GJ9H%|EW&M0`?PJG@J{gECZDq2G^f*RE>4rBs;9j|@*1-o2s>3iXHa9yFypjwG8SsHm zAnecv%sDun-j10i;_FMesdk1F_&m9lp1Tno=y&~U%^9r1eaF!5zc2?i6L-_l0!o&d zdBjUJ-se^>%n-mAKRT`B>A9IeqSq~fc0PHFy*|G*CdPX}52UTkhc6(ZFly19y&Q_i zT=7jlb*@vwN89HDUGZp3dxPrG(taQ2BeI!zD6Y8TWx&VB3pA^?ki8s8$gWXWyhEY5 zDn=^h3ne9p3yii#Hz4;V15&jx985&qTXOml(VF3?ty7U_K$gs8B&?B%Yc*iI^BjgBD}!FVEHD2L1{OXk27X@toqY9tQkw+@mho None: + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('dev_companies', + sa.Column('dev_id', sa.Integer(), nullable=False), + sa.Column('company_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['company_id'], ['companies.id'], name=op.f('fk_dev_companies_company_id_companies')), + sa.ForeignKeyConstraint(['dev_id'], ['devs.id'], name=op.f('fk_dev_companies_dev_id_devs')), + sa.PrimaryKeyConstraint('dev_id', 'company_id') + ) + op.create_table('freebies', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('item_name', sa.String(), nullable=False), + sa.Column('value', sa.String(), nullable=True), + sa.Column('dev_id', sa.Integer(), nullable=True), + sa.Column('company_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('dev_companies') + # ### end Alembic commands ### diff --git a/lib/models.py b/lib/models.py index 2681bee5a..b329d2374 100644 --- a/lib/models.py +++ b/lib/models.py @@ -1,4 +1,4 @@ -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 @@ -9,21 +9,63 @@ Base = declarative_base(metadata=metadata) +dev_company = Table( + 'dev_companies', + Base.metadata, + Column('dev_id', ForeignKey('devs.id'), primary_key=True), + Column('company_id', ForeignKey('companies.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()) + devs = relationship('Dev', secondary=dev_company, backref=backref('companies', lazy='dynamic')) + freebies = relationship('Freebie', backref='company') def __repr__(self): return f'' + 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', backref='dev') def __repr__(self): return f'' + + def received_one(self, item_name): + return any(freebie.item_name == item_name for freebie in self.freebies) + + def give_away(self, dev, freebie): + if freebie in self.freebies: + freebie.dev = dev + return True + return False + +class Freebie(Base): + __tablename__ = 'freebies' + id = Column(Integer(), primary_key=True) + item_name = Column(String(), nullable=False) + value = Column(Integer) + dev_id = Column(Integer(), ForeignKey('devs.id')) + company_id = Column(Integer(), ForeignKey('companies.id')) + + def print_details(self): + return f"{self.dev.name} owns a {self.item_name} from {self.company.name}" + + def __repr__(self): + return f"Freebie {self.id}: item_name={self.item_name}, value={self.value}" diff --git a/lib/seed.py b/lib/seed.py index b16becbbb..895b98ffe 100644 --- a/lib/seed.py +++ b/lib/seed.py @@ -1,3 +1,55 @@ -#!/usr/bin/env python3 +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker +from faker import Faker +from models import Base, Dev, Company, Freebie +import random -# Script goes here! +engine = create_engine('sqlite:///freebies.db') +Session = sessionmaker(bind=engine) +session = Session() + +faker = Faker() + +print("Seeding data...") + +def seed_data(): + # Clear existing records + session.query(Freebie).delete() + session.query(Dev).delete() + session.query(Company).delete() + session.commit() + + companies = [] + devs = [] + freebies = [] + + # Create companies + for i in range(10): + company = Company(name=faker.company(), founding_year=faker.year()) + session.add(company) + companies.append(company) + + # Create developers + for i in range(50): + dev = Dev(name=faker.name()) + session.add(dev) + devs.append(dev) + + # Create freebies and set relationships + for i in range(50): + dev = random.choice(devs) + company = random.choice(companies) + freebie = Freebie( + item_name=faker.name(), + value=random.randint(0, 100), + dev=dev, # Set the dev relationship + company=company # Set the company relationship + ) + session.add(freebie) + freebies.append(freebie) + + session.commit() + print("Seed data generated successfully!") + +if __name__ == '__main__': + seed_data() From ecc4b5e293537ac8c951b043a7314e7c4d64e3ce Mon Sep 17 00:00:00 2001 From: Billy Eskein Date: Fri, 7 Mar 2025 08:22:55 +0300 Subject: [PATCH 2/2] Update lib/freebies.db --- lib/freebies.db | Bin 32768 -> 32768 bytes lib/seed.py | 48 +++++++++++++++++++++++++----------------------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/lib/freebies.db b/lib/freebies.db index 18369798bd3412ea34095b808e2246f4a94f8548..3ec1d90e37e582114d7c53633b01d72c8bc2286a 100644 GIT binary patch delta 2697 zcmYjTU2Gd!86E#*Y{xTmV<)!r+uXFxCT)`@wwoUdu~nS34QbMilAvmV2X5?Jd+PC> z=#HIqq7^Pe0)bY*zQ7A00jqsM2(kMD2m}%mh!-kAqS^-#AR!PET0r{_=gv4~ALssj z-~G;a&iUr))9BNu(JxO#M&6j*jEsE$lW#5MQyTd@c}{*n-XfnRHL_1`lSz_#Co}X< ztCty!YgeLG$?6XG=|@B@@z0yVTG`a9xk@z!7#Hh9!;&~>a!W=f)+2T=G3N8~ro6%L6d#*TV4nJR@n@l>m9K@>PjFeWm6K;mY8^UCBf%@wcIPT$_n*GsjuPl@?F@dMXyzJ`}~fIZCf6G1W0^O3l=813g?3{r5%N&LptG_7R3#x?RDd6)c>yhGk3Um~9- zZSpa4kF1h8k|zo4ed{mQZ>^tN-?6@Gea7;vnss2kY+bj;E#3UL`6u(4`D63D=GV>F zP2c3^fmt<6=4CT${MY!G@viZ6<89+>#^;UK0QHd3OP6BW)Q(H{rCsBhVobZX!#$4! z5VMMw52K+k6GIm^a41t6w_w!aaT4teU){%H*yol9@>s$vo_u4QlL5fJhvFr ziknSodmR^Tl7Pmqb73yTw3!{ZDQLB)K*`)d+C970WZa=!UD;%9>v~MPvgbOEuNIiF zuHk!&o!WJ}>z?p)YaZYC`6=GC&4ggq9KQE?qv6wl0GXE%a*GKY5mhGiI6E8DZtQT$ z+dkc^)q}lE?`lx-qel`%LnMz2as{>Bk%)YNnk8~wM(kbNWAq_&T3nhlcz#v-47pKp zh9U%bc*=!3;IJAe(+VER8?N+e6|E(gu&~Qe34P#7kYac$rY-KXP7koR=pK_DTk!Mj zB%WB6cBjLHPY;@IoqN`V%HFj-x`$+3X2)^n$bR%l9oZ0d$Bx%K+cP)wUUa0PSl#wK@8 zybOu;RF_m&_jw1Q!3_)GZbF>LXtZb$6IEQi={^@7(+IfZ(|eMECnWv!fEh;p%}{CVaincMl}+JHa@6=fT1L!Dob<6 z_Q0$M%xk{AAE7PsIjxj7l{Y?vH+~~+k`wY#@-mqvY3o1M@2#I$Z(6TgUF#Fp79>Ap zzHk1~{Dt{F^DE}3%!avdu9%Z%)cA+-%=n@4E#r&Esqw0D+n6`Z^n2;wrGJ$EcKQqH zlk~^ax6`vQfNu`=@&mdyn~6krT))O?=#!O|XneG!YuB*8acnmjpxb5=jV>)uCC7`p zwv>sa0&uo$hRUn%S(}MlrMcl{U7N-&P@zR(;C^xaQhanN3>Bi%htFH9jHC)Td%8BK z&T~fz5?U49D=rTtbBnrm1sheg3wl*}uB~5778b(uFm>3npm!Z#h+E4;iSZk{wutkp zeq%*4E)lc|JLLUDt}(J7mY`6A0QB!WIqCr?k?G4~|{awHxYc=nZ$dY;=*X zxICE3%>x_~i5&S*USEKvnb_zYl95PiLv)%hWO$+9^2EeTNQDbwyH&Ca%PbD3^0Oh- zP-@Gk54ggtw_em!*{eVew+?G=M``iNYBrg>5~l78G~i6hOpaXEwV9w!*k^!Nc|EI- z&4eZNsZ4iRt%VXwtMjQm1!9POQJw2SXytrtbUJ8CFQU{1i{dadV82!@B@35cG$kNs z6`mp2O7Y~_RG8+%+V0fP;5gp;`naB(4Ev=#Kyd}0Uo0)BauZ<{iYD++TMgS=bE*6| zk^{gk-aB?7WV*#2?uv4}Fczl1(AW`|(l3{$qq)&A{)X37{{-7z(OFrU8q60$NCUpX zHkxi%l-HLMBl!=&6xiL`@}8wbfnKx4t6|3yHO<vXkO|9x!^7a=iB$}S)zuq%ZYV4RYE$tW zZcqBF% zIQ)qk!leRMD^@kpxC0Qrczd(KwM*?1up-hs_Q zpZ$(kR%he6q^dmy#RW_ZW^APrA4>$b>(`ZoE^Yl zPvMP?;p5SG_=rPxs%AR=;-JX$^2$^!7YlDf44BIgeK>ZpG?yww!?$fPHHr>g4|Bt- VREo)b1REfIh<_^_fGZ1w{{xhX%FzG- literal 32768 zcmeI5TWlL?6@bUriDS=ZGY1QdPi4f9yZ;knv2I z8Mk$KShdR{A@P7fD+CV+39(N|NFZ(kgoGA}i?kpf7K8+g1ggXfix3aX6P$m>PUC1R zv=2zDaz;(iasaGqRT}<=1naSMO1+adw3-ud;jlPc(5!#i*Z9y?H^pQ`*?dmF|+8 zg}Y=-t&a1R`CHrN-BJ#`Acx2MZQu5vC}_QfaLDSdQek6lo8Le7WWhKo6;=zS!gjt; zCa#z-{x1expZDRVQ?D!U(CMt<>bl1teK;T{Mn^rLY&f9#;xmgKC&3Qn9hW$FE_gz$ zgZ-1h-ZeEH3|%#ot*ANfcVXIL{C@_v(~9fZd!?HV1`}JO9zoTs?1A-h4a#tzHf+N= z=gOYI-cNO$iWR?@h{rt-$J=?a;JOvKm<1?{rxyMBdgqndLE6dw!>~_G3=Mf6GRMkU z=Fi^vJM5i_--FRZqoG$-{b;|*sM#)nr+72&5fc*=o<||a8>+GTfm+$W$4pB#^b4on z4$m%Jm8+t(ZQ_Cr6GNso7w=DBC}f`{)zcAq~ z83!ttP2~;_4BHm}6b<@?VJ~PgRm)lUvz~xo81WV~O@#$hH(^*oe4Y6HLe9HxG%VZD zC&?NNAnA_HRhUZPD}EdIarJp>a)aEPvY}hz?|Qsk*>c0yz{xe!XqwQ@XFGLB%XLHsG-|ED8{puDa8QTe&@9pyFURpn*HR;Y4Yc|jRddK9nxH~B63 z*Yc0$ughPOKPB7ppkPVPW>OpgwL z1Xi(=8Y!tTqfTQ<9uuUkO3z|SoW-;SG4;bOdn#CGMdkFi43kPx zIL$#NwW3zQj+>|zqj6LN-A!2rR@-U?N(}<2us+Er%xpnonSRRo*$mQU$0A^Rol#(H zk}`V$oASOeEQHG^kSkcY%5i9#+|8?*Rct`LPBkqSf*ada#H$iGcY#xGaok}C2T>6M zT?UsSs8!Vh149vAPl6FVkN^@u0!RP}AOR$R1dzb{jle)U zC``mWo}17%&g>f5p;c(wrJ3wdS3DIIMq-{&?!;6zvPR8{O4FI%o6yv(kvxT#YfUp2=KZ1mNyiOO!Bmf-Gn>}o`w8bWy}tg5pfIX%Kip369P}FN zivwccji4|Lx{BZ*g|28rPcKNJ#5k;We1qm?SP8xM#_@dmdN48OUdY#|#fXEU+60$^ ziP7_SkUOS&RI?Z6dwj|3EdZ?!{hSFs_+~ae=uM6|FhlJqTix+X+3Wq++#rA=Z_cJw z=zyP_4FvkG0x}4q)px$fj%a4WH~74ZqaE5EV4>2wm0eK8{$X&dHxyc?<^lAsyA9K+ z+1Vs zmp!}GJ9H%|EW&M0`?PJG@J{gECZDq2G^f*RE>4rBs;9j|@*1-o2s>3iXHa9yFypjwG8SsHm zAnecv%sDun-j10i;_FMesdk1F_&m9lp1Tno=y&~U%^9r1eaF!5zc2?i6L-_l0!o&d zdBjUJ-se^>%n-mAKRT`B>A9IeqSq~fc0PHFy*|G*CdPX}52UTkhc6(ZFly19y&Q_i zT=7jlb*@vwN89HDUGZp3dxPrG(taQ2BeI!zD6Y8TWx&VB3pA^?ki8s8$gWXWyhEY5 zDn=^h3ne9p3yii#Hz4;V15&jx985&qTXOml(VF3?ty7U_K$gs8B&?B%Yc*iI^Bj