From 07cff17a5fb3170f6e37377046fb8ecf621b0e96 Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Mon, 26 May 2025 19:51:48 +0300 Subject: [PATCH 01/23] Adds freebie class --- lib/models.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/lib/models.py b/lib/models.py index 2681bee5a..5a3f50764 100644 --- a/lib/models.py +++ b/lib/models.py @@ -2,6 +2,8 @@ from sqlalchemy.orm import relationship, backref from sqlalchemy.ext.declarative import declarative_base +# naming conventions for constraints + convention = { "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s", } @@ -15,6 +17,8 @@ class Company(Base): id = Column(Integer(), primary_key=True) name = Column(String()) founding_year = Column(Integer()) + # relationships + freebies=relationship("Freebie", back_populates="company") def __repr__(self): return f'' @@ -25,5 +29,28 @@ class Dev(Base): id = Column(Integer(), primary_key=True) name= Column(String()) + # relationships + freebies=relationship("Freebie", back_populates="dev") + def __repr__(self): return f'' +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'' + + + # Here we added Freebie class because the project is called freebie tracker + # Establish relationship between companies, devs and freebies + + From 4f7456b0c0ea6dd8b62d94cfaeca81e4d076d2ab Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Mon, 26 May 2025 20:25:47 +0300 Subject: [PATCH 02/23] Import modules and classes to seed --- lib/seed.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/seed.py b/lib/seed.py index b16becbbb..9536ea598 100644 --- a/lib/seed.py +++ b/lib/seed.py @@ -1,3 +1,8 @@ #!/usr/bin/env python3 -# Script goes here! +from sqlalchemy.orm import sessionmaker +from sqlalchemy import create_engine + +from models import Company, Dev, Freebie + + From 88c8d1f46b1e43bb00b3fbb626b1436616667f27 Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Mon, 26 May 2025 20:29:24 +0300 Subject: [PATCH 03/23] Create some companies --- lib/seed.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/seed.py b/lib/seed.py index 9536ea598..467b536fe 100644 --- a/lib/seed.py +++ b/lib/seed.py @@ -5,4 +5,23 @@ from models import Company, Dev, Freebie +# create engine and session + +engine=create_engine("sqlite:///freebies.db") +Session=sessionmaker(bind=engine) +session=Session() + +def seed_data(): + # create some companies# create engine and session + +engine=create_engine("sqlite:///freebies.db") +Session=sessionmaker(bind=engine) +session=Session() + +def seed_data(): + # create some companies + c1=Company(name='Jedaq', founding_year=2005) + c2=Company(name='Amazon', founding_year=2010) + + From 9cfb5c37f545e08f2b3301dcc03cc9c3766c587c Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Mon, 26 May 2025 20:29:51 +0300 Subject: [PATCH 04/23] Create some devs --- lib/seed.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/seed.py b/lib/seed.py index 467b536fe..cc99f1942 100644 --- a/lib/seed.py +++ b/lib/seed.py @@ -23,5 +23,13 @@ def seed_data(): c1=Company(name='Jedaq', founding_year=2005) c2=Company(name='Amazon', founding_year=2010) - + # now let me create some devs here + d1=Dev(name="Alice") + d2=Dev(name="Aquila") + + # Add companies and devs to session + session.add_all([c1,c2,d1,d2]) + session.commit() #commit to generate ids for foreign keys + + # create freebies liked w From 351c56febbead300db8e1bebedba623178230d2e Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Mon, 26 May 2025 20:30:48 +0300 Subject: [PATCH 05/23] add companies and devs to session --- lib/seed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/seed.py b/lib/seed.py index cc99f1942..bbc0ce9e1 100644 --- a/lib/seed.py +++ b/lib/seed.py @@ -31,5 +31,5 @@ def seed_data(): session.add_all([c1,c2,d1,d2]) session.commit() #commit to generate ids for foreign keys - # create freebies liked w + # From 7c32b89c568be9970e9a6816e421cc660f349a60 Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Mon, 26 May 2025 20:33:52 +0300 Subject: [PATCH 06/23] Create freebies linked to companies and devs --- lib/seed.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/seed.py b/lib/seed.py index bbc0ce9e1..e5e11dea7 100644 --- a/lib/seed.py +++ b/lib/seed.py @@ -31,5 +31,9 @@ def seed_data(): session.add_all([c1,c2,d1,d2]) session.commit() #commit to generate ids for foreign keys - # + #create freebies linked to companies and devs + + f1 =Freebie(item_name='Sticker Pack', value=0, company_id=c1.id, dev_id=d1.id) + f2 =Freebie(item_name='T-shirt', value=20, company_id=c2.id, dev_id=d2.id) + f3 =Freebie(item_name='Mug', value=10, company_id=c1.id, dev_id=d2.id) From 9025dda6e7d99442affc7d1f19cf66268e1d390d Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Mon, 26 May 2025 20:35:51 +0300 Subject: [PATCH 07/23] Add freebies and commit --- lib/seed.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/seed.py b/lib/seed.py index e5e11dea7..65ab53d74 100644 --- a/lib/seed.py +++ b/lib/seed.py @@ -37,3 +37,11 @@ def seed_data(): f2 =Freebie(item_name='T-shirt', value=20, company_id=c2.id, dev_id=d2.id) f3 =Freebie(item_name='Mug', value=10, company_id=c1.id, dev_id=d2.id) + # add freebies and commit + session.add_all([f1,f2,f3]) + session.commit() + + print("Seed data added successfully!") + +if __name__ =="__main__": + seed_data() From 99d7781a45f9431d855bffc43a9f0daa5aae2686 Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Mon, 26 May 2025 20:40:30 +0300 Subject: [PATCH 08/23] Creates run.py file --- freebies.db | 0 lib/__pycache__/models.cpython-38.pyc | Bin 0 -> 1976 bytes lib/seed.py | 47 +++++++++++--------------- run.py | 0 4 files changed, 19 insertions(+), 28 deletions(-) create mode 100644 freebies.db create mode 100644 lib/__pycache__/models.cpython-38.pyc create mode 100644 run.py diff --git a/freebies.db b/freebies.db new file mode 100644 index 000000000..e69de29bb diff --git a/lib/__pycache__/models.cpython-38.pyc b/lib/__pycache__/models.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..96d6abd400338a5c7f6e9565d4a18d98ff8b18c3 GIT binary patch literal 1976 zcmb7FOOG2x5T5Rt@jN`^^&%c31Xuw<@nP4Xa6znAh>aE@L@o)JmZH||ba_45c{n}x z3R~Qq1DE^(P<}vu5`E>wU&sZjW@f$4ij~4hU9Re9_4n1+{yC0A3%@^q|7!Ym&$9la zVEc10_!e9J8yaOPmRkiAtl)wdwy+CFIE5=*Mq@nh6`t@4U-(UI=RpyQ5Pe6v854bQ zp|5(+nTQ~SNO|bR-&@L8!81z*5U*`9z&KQWjQdTzgK?x{jN>LAs=-5RwDUJ+V~t!B zo>UsLv+_q+n%;4hFN)H5Ka_Jg18sT_=Q=CTjQUw$@De zZ9jSegak5z%SB&#%712wNCgO0XuRX9m?h;>1Zm@BP(OOfOn;`cBGF5Ej@Wr88sIbo zH!+Xezl%he_)O;Y&_L|unG>lbN61cBizm* z{OGraeDc!L@8hahkH^!hfbkPhnaYysSiuG4)vQ3U#%ZNsJewjF_ZojcohEq>!E9-KDK*Trl&hft zjg)&sA{ldkw98zef`n?t3ySw6}BYYr(Yz{@E1>;^M`2uca?@K!2Qd8Yd zTMX{LF@tw-BmFrU+RcRB6C^WbdU#{}ZTa1$DW8$Kkz^`d+ODR$MUq*>eCDH+20UU& zHjO_R?V7NDnkRWWg<{zpx>Z?CQQ=>qWd>K14k}%=N%%M-Zf%XgFY|+~{|+6{QoO_E xi?2z~#`zB4v6eR~xR&Vucm|Ar*uFkTL~2bMy3K|xa=FF-aqN(Xd>9S;{{mV`woU*5 literal 0 HcmV?d00001 diff --git a/lib/seed.py b/lib/seed.py index 65ab53d74..fe1a8abe6 100644 --- a/lib/seed.py +++ b/lib/seed.py @@ -5,43 +5,34 @@ from models import Company, Dev, Freebie -# create engine and session - -engine=create_engine("sqlite:///freebies.db") -Session=sessionmaker(bind=engine) -session=Session() +# Create engine and session +engine = create_engine("sqlite:///freebies.db") +Session = sessionmaker(bind=engine) +session = Session() def seed_data(): - # create some companies# create engine and session - -engine=create_engine("sqlite:///freebies.db") -Session=sessionmaker(bind=engine) -session=Session() + # Create some companies + c1 = Company(name="TechCorp", founding_year=2005) + c2 = Company(name="DevSolutions", founding_year=2010) -def seed_data(): - # create some companies - c1=Company(name='Jedaq', founding_year=2005) - c2=Company(name='Amazon', founding_year=2010) - - # now let me create some devs here - d1=Dev(name="Alice") - d2=Dev(name="Aquila") + # Create some devs + d1 = Dev(name="Alice") + d2 = Dev(name="Bob") # Add companies and devs to session - session.add_all([c1,c2,d1,d2]) - session.commit() #commit to generate ids for foreign keys - - #create freebies linked to companies and devs + session.add_all([c1, c2, d1, d2]) + session.commit() # Commit to generate ids for FKs - f1 =Freebie(item_name='Sticker Pack', value=0, company_id=c1.id, dev_id=d1.id) - f2 =Freebie(item_name='T-shirt', value=20, company_id=c2.id, dev_id=d2.id) - f3 =Freebie(item_name='Mug', value=10, company_id=c1.id, dev_id=d2.id) + # Create freebies linked to companies and devs + f1 = Freebie(item_name="Sticker Pack", value=0, company_id=c1.id, dev_id=d1.id) + f2 = Freebie(item_name="T-Shirt", value=20, company_id=c2.id, dev_id=d2.id) + f3 = Freebie(item_name="Mug", value=10, company_id=c1.id, dev_id=d2.id) - # add freebies and commit - session.add_all([f1,f2,f3]) + # Add freebies and commit + session.add_all([f1, f2, f3]) session.commit() print("Seed data added successfully!") -if __name__ =="__main__": +if __name__ == "__main__": seed_data() diff --git a/run.py b/run.py new file mode 100644 index 000000000..e69de29bb From 3aac8407199677f12414b7d7d96fb85f7586db4b Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Mon, 26 May 2025 20:42:17 +0300 Subject: [PATCH 09/23] Import modules and classes to run.py --- run.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/run.py b/run.py index e69de29bb..b61aad0ab 100644 --- a/run.py +++ b/run.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python3 + +from sqlalchemy.orm import sessionmaker +from sqlalchemy import create_engine +from lib.models import Dev, Company, Freebie + + + + From 4011917077387d194bd11fa4a402c2eb56afccb4 Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Mon, 26 May 2025 20:46:55 +0300 Subject: [PATCH 10/23] Sets up database session --- run.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/run.py b/run.py index b61aad0ab..e07de1ad7 100644 --- a/run.py +++ b/run.py @@ -2,7 +2,15 @@ from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine -from lib.models import Dev, Company, Freebie + + +# set up DB session + +engine=create_engine("sqlite:///freebies.db") +Session =sessionmaker(bind=engine) +session=Session() + + From 0cd30f0eb8e8eaedb19ea152b51b6f7714ed76c3 Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Mon, 26 May 2025 20:55:27 +0300 Subject: [PATCH 11/23] :Creates a function to list all devs --- run.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/run.py b/run.py index e07de1ad7..00a8cf018 100644 --- a/run.py +++ b/run.py @@ -2,6 +2,7 @@ from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine +from lib.models import Dev, Company, Freebie # set up DB session @@ -11,6 +12,17 @@ session=Session() +def print_line(): + print("_"*60) + +def list_devs(): + devs=session.query(Dev).all() + print_line() + for dev in devs: + print(f"{dev.id}: {dev.name}") + print_line() + + From cb94fb7891529a236f3dc109cd6b0cb298dabef6 Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Mon, 26 May 2025 20:56:15 +0300 Subject: [PATCH 12/23] Adds function to list all companies --- run.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/run.py b/run.py index 00a8cf018..8f8756e16 100644 --- a/run.py +++ b/run.py @@ -22,8 +22,11 @@ def list_devs(): print(f"{dev.id}: {dev.name}") print_line() +def list_companies(): + companies=session.query(Company).all() + print_line() + for company in companies: + print(f"{company.id} : {company.name} (Founded {company.founding_year})") + print_line() - - - - + From f335c15a2e691ab435f9b5e742b6dbc101b89898 Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Mon, 26 May 2025 20:57:02 +0300 Subject: [PATCH 13/23] Creates a function to list all freebies --- run.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/run.py b/run.py index 8f8756e16..21f5c91b6 100644 --- a/run.py +++ b/run.py @@ -30,3 +30,20 @@ def list_companies(): print_line() + +def list_freebies(): + freebies = session.query(Freebie).all() + print_line() + for freebie in freebies: + print(f"{freebie.item_name} (worth ${freebie.value})") + print(f" - Given by: {freebie.company.name}") + print(f" - Received by: {freebie.dev.name}") + print_line() + + + + + + + + From b08a2a3bb60efbe5835855ec5a6a2f710db1066f Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Mon, 26 May 2025 20:58:10 +0300 Subject: [PATCH 14/23] define main function that prints out option on the terminal --- run.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/run.py b/run.py index 21f5c91b6..2c99ed804 100644 --- a/run.py +++ b/run.py @@ -42,7 +42,32 @@ def list_freebies(): - +def main(): + while True: + print("\nFREEBIE TRACKER CLI") + print("1. List all developers") + print("2. List all companies") + print("3. List all freebies") + + print("0. Exit") + + choice=input("Select and option: ") + + if choice == "1": + list_devs() + elif choice == "2": + list_companies() + elif choice == "3": + list_freebies() + elif choice == "0": + print("Goodbye!") + break + else: + print("Invalid option. Try again.") + +if __name__ == "__main__": + main() + From 52c6e5d58a0c4f84ea8579616dd3a734196e840b Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Mon, 26 May 2025 21:48:23 +0300 Subject: [PATCH 15/23] Add cli actions --- freebies.db | Bin 0 -> 16384 bytes lib/__pycache__/models.cpython-38.pyc | Bin 1976 -> 1976 bytes lib/seed.py | 4 ++- run.py | 40 ++++++++++++++++++++------ 4 files changed, 35 insertions(+), 9 deletions(-) mode change 100644 => 100755 run.py diff --git a/freebies.db b/freebies.db index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9cd5daf218ad33e46cf6ac0767719825470ee97e 100644 GIT binary patch literal 16384 zcmeI&J#W)M7zgmXa~e0Pf~%G)1B!Y}r9=XjegWKYEfJ|xY=hJRS&nmQt-QE$ok$&n z#K4E)qcE~md<0Z6F>_9E(gbK%D*aEoJeS9h@8##olASlrFp<0)#REU#`(%?)N?veI z2w77-r+U^jHMsqsW*6>=YvlR(Q%MzQrO(8Ojgksz5P$##AOHafKmY;|fB*y_aG$`3 z_nKa=ROrW2;58?0>E)drI;l;0(+g?WmRM)y|0G@2Ttz9?CL2^Q@9xrxoUSrI(tN;{ z)|;pAc#f-!cB9d-6AsV3E9u9#ALXCBN#D(x@r@Wi)DId2AOHafKmY;|fB*y_009U< z00IwAV2kC*9(yUrPShVIVKltduOHDIsW4Xt=k+MQ(7(>!|8I!#)3|wX2gHUU009U< z00Izz00bZa0SG_<0ucC%K%Qx2`ygtsQ;n3(ei+E Date: Mon, 26 May 2025 21:55:45 +0300 Subject: [PATCH 16/23] include the add dev function --- freebies.db | Bin 16384 -> 16384 bytes run.py | 23 +++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/freebies.db b/freebies.db index 9cd5daf218ad33e46cf6ac0767719825470ee97e..0ec4a896c6c662e63c72d590abbfe26e4ac3d7a4 100644 GIT binary patch delta 53 zcmZo@U~Fh$oFL7}Hc`fzk!@qb5_v9W{znY_-}vA0KiVv)aD|_Ti Date: Mon, 26 May 2025 21:59:48 +0300 Subject: [PATCH 17/23] Adds the add_company functionality --- run.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/run.py b/run.py index 40cdd6d80..74b31d2b3 100755 --- a/run.py +++ b/run.py @@ -72,6 +72,27 @@ def add_dev(): print(f"An error occurred: {e}") session.rollback() +def add_company(): + name = input("Enter company name: ") + founding_year = input("Enter founding year: ") + + if not founding_year.isdigit(): + printMessage("Founding year must be a number.") + return + + try: + company = Company( + name=name, + founding_year=int(founding_year) + ) + session.add(company) + session.commit() + printMessage("Company added successfully!") + except Exception as e: + printMessage(f"Error occurred: {e}") + session.rollback() + + @@ -88,6 +109,8 @@ def main(): "3": list_freebies, "4": show_developer_freebies, "5": add_dev, + "6": add_company, + } @@ -98,6 +121,8 @@ def main(): print("3. List all freebies") print("4. Show all freebies for a developer") print("5. Add a new developer") + print("6. Add a new company") + print("0. Exit") choice=input("Select and option: ") From 1f9b012f0a12c522d33af1116f519d853dc5f95d Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Tue, 27 May 2025 14:13:23 +0300 Subject: [PATCH 18/23] Completed the project with sqlaclchemy --- freebies.db | Bin 16384 -> 16384 bytes lib/__pycache__/models.cpython-38.pyc | Bin 1976 -> 1976 bytes lib/models.py | 2 + run.py | 204 +++++++++++++++++++++++++- 4 files changed, 204 insertions(+), 2 deletions(-) diff --git a/freebies.db b/freebies.db index 0ec4a896c6c662e63c72d590abbfe26e4ac3d7a4..15fa3c476ffd76a8a0c2e40a5180d685d1358220 100644 GIT binary patch delta 354 zcmY+7y-LGi6o${q&leLdZ`ulKD>Mj>(#adBIw%x`dI827YHVrxlXh?l6gn#%9E*b& zpbmNg9TfsDDxF+hM4X)cYC-gcGri||pD5xe;?peKXUiLGU+rHYiF?w}BlIxF9fla* zB<&`O8P;fB*{*l}a@c7*AtGDeZxVQt<`H3p54<8qEX~(gv{w>b(yth_5 x@>}7&rl&MPt20EU(3eEZ*_GgrW^O7YN~(f#Y;wV`IE|Vcda9D*31pgop>K@dQrQ3i delta 171 zcmZo@U~Fh$oFL7}Hc`fzk!@qbLVj)r1_mbnI}H3E`0s31R9MVEaf0sTJMtoOe2gp% zvP>bV$r;Z1MFs3vd4UR<`5!Uxf8&40{|KtoaPlL45eW`PW(IM`oXq4@h@!I${BQVg z@t=h%k}>9HW@8X$Iip%T)Q z+nJlCZ?UALmKBE-@q;7r;f(UUC!44vnK?GK}fh1Ib1jwRdkoPzkS(x}3 zxtMvFz~adh1tljdvgY%EoD4Px=!MC1SQXenE-zA#Ci zu4Ylll>sqjL4+KLkOvXWAc6%%D1Zo75FrL4*g=F6h`{PLkc2Xj02yBl@*W2x3lkqB z7c&nNSUh>6pyXsl)_fk2lfmWyy)bzWs{$LyV2z0!_' + + class Freebie(Base): __tablename__='freebies' id =Column(Integer, primary_key=True) diff --git a/run.py b/run.py index 74b31d2b3..2db0d1166 100755 --- a/run.py +++ b/run.py @@ -14,6 +14,7 @@ def print_line(): print("_"*60) + # list all devs here def list_devs(): devs=session.query(Dev).all() @@ -29,7 +30,7 @@ def list_companies(): print(f"{company.id} : {company.name} (Founded {company.founding_year})") print_line() - + # list all freebies def list_freebies(): freebies = session.query(Freebie).all() @@ -39,6 +40,8 @@ def list_freebies(): print(f" - Given by: {freebie.company.name}") print(f" - Received by: {freebie.dev.name}") print_line() + + # show freebies for a developer def show_developer_freebies(): name = input("Enter the developer's name: ") @@ -56,6 +59,8 @@ def show_developer_freebies(): print(f"Freebies for {dev.name}:") for freebie in dev.freebies: print(f"- {freebie.item_name} from {freebie.company.name} (Worth: ${freebie.value})") + + # add a new dev def add_dev(): name = input("Enter the developer's name: ") @@ -92,6 +97,187 @@ def add_company(): printMessage(f"Error occurred: {e}") session.rollback() + # add a new freebie +def add_freebie(): + try: + print("\n--- Add a New Freebie ---") + + item_name = input("Enter the freebie item name: ") + + while True: + value = input("Enter the value of the freebie: ") + if value.isdigit(): + value = int(value) + break + else: + print("Value must be a number. Try again.") + + dev_id = input("Enter the ID of the developer receiving the freebie: ") + company_id = input("Enter the ID of the company giving the freebie: ") + + if not (dev_id.isdigit() and company_id.isdigit()): + print("Developer ID and Company ID must be numbers.") + return + + freebie = Freebie( + item_name=item_name, + value=value, + dev_id=int(dev_id), + company_id=int(company_id), + ) + + session.add(freebie) + session.commit() + printMessage(" Freebie added successfully!") + + except Exception as e: + print(f" An error occurred: {e}") + session.rollback() + +# delete a dev here +def delete_dev(): + try: + dev_id = input("Enter the ID of the developer to delete: ") + if not dev_id.isdigit(): + print(" ID must be a number.") + return + + dev = session.query(Dev).get(int(dev_id)) + if not dev: + print(" Developer not found.") + return + + session.delete(dev) + session.commit() + printMessage(f" Developer '{dev.name}' deleted successfully!") + + except Exception as e: + print(f" Error: {e}") + session.rollback() +# delete a company function +def delete_company(): + try: + company_id = input("Enter the ID of the company to delete: ") + if not company_id.isdigit(): + print("ID must be a number.") + return + + company = session.query(Company).get(int(company_id)) + if not company: + print("Company not found.") + return + + session.delete(company) + session.commit() + printMessage(f" Company '{company.name}' deleted successfully!") + + except Exception as e: + print(f" Error: {e}") + session.rollback() + +# delete a freebie function here +def delete_freebie(): + try: + freebie_id = input("Enter the ID of the freebie to delete: ") + if not freebie_id.isdigit(): + print(" ID must be a number.") + return + + freebie = session.query(Freebie).get(int(freebie_id)) + if not freebie: + print(" Freebie not found.") + return + + session.delete(freebie) + session.commit() + printMessage(f" Freebie '{freebie.item_name}' deleted successfully!") + + except Exception as e: + print(f"Error: {e}") + session.rollback() + +# update a dev here : +def update_dev(): + while True: + dev_id = input("Enter the developer ID: ") + if not dev_id.isdigit(): + print("Developer ID must be a number. Try again!") + continue + + try: + dev = session.query(Dev).filter_by(id=dev_id).one_or_none() + if dev: + name = input("Enter the updated name: ") + + dev.name = name or dev.name + session.commit() + printMessage("Developer updated successfully!") + return + else: + printMessage("Invalid Developer ID. Try again!") + except Exception as e: + print(f"Error occurred: {e}") + session.rollback() +# update company here: + +def update_company(): + while True: + company_id = input("Enter the company ID: ") + if not company_id.isdigit(): + print("Company ID must be a number. Try again!") + continue + + try: + company = session.query(Company).filter_by(id=company_id).one_or_none() + if company: + name = input("Enter the updated company name: ") + year = input("Enter the updated founding year: ") + + company.name = name or company.name + company.founding_year = int(year) if year.isdigit() else company.founding_year + + session.commit() + printMessage("Company updated successfully!") + return + else: + printMessage("Invalid Company ID. Try again!") + except Exception as e: + print(f"Error occurred: {e}") + session.rollback() + +# update freebie here + +def update_freebie(): + while True: + freebie_id = input("Enter the freebie ID: ") + if not freebie_id.isdigit(): + print("Freebie ID must be a number. Try again!") + continue + + try: + freebie = session.query(Freebie).filter_by(id=freebie_id).one_or_none() + if freebie: + name = input("Enter the updated item name: ") + value = input("Enter the updated value: ") + + freebie.item_name = name or freebie.item_name + freebie.value = int(value) if value.isdigit() else freebie.value + + session.commit() + printMessage("Freebie updated successfully!") + return + else: + printMessage("Invalid Freebie ID. Try again!") + except Exception as e: + print(f"Error occurred: {e}") + session.rollback() + + + + + + + @@ -110,6 +296,14 @@ def main(): "4": show_developer_freebies, "5": add_dev, "6": add_company, + "7": add_freebie, + "8": delete_dev, + "9": delete_company, + "10": delete_freebie, + "11": update_dev, + "12": update_company, + "13": update_freebie, + } @@ -122,7 +316,13 @@ def main(): print("4. Show all freebies for a developer") print("5. Add a new developer") print("6. Add a new company") - + print("7. Add a new freebie") + print("8. Delete a developer") + print("9. Delete a Company") + print("10. Delete a Freebie") + print("11. Update a developer") + print("12. Update a company") + print("13. Update a freebie") print("0. Exit") choice=input("Select and option: ") From 8ccbadc187979045177f5a438d3ab724e5abd53d Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Tue, 27 May 2025 15:16:30 +0300 Subject: [PATCH 19/23] Debug the alembic files --- lib/alembic.ini => alembic.ini | 4 +-- freebies.db | Bin 16384 -> 20480 bytes lib/__pycache__/models.cpython-38.pyc | Bin 1976 -> 1976 bytes lib/__pycache__/seed.cpython-38.pyc | Bin 0 -> 1005 bytes lib/migrations/__pycache__/env.cpython-38.pyc | Bin 0 -> 1443 bytes lib/migrations/env.py | 28 +++++++----------- ...bf48c_create_companies_devs.cpython-38.pyc | Bin 0 -> 1070 bytes .../7a71dbf71c64_create_db.cpython-38.pyc | Bin 0 -> 705 bytes lib/seed.py | 10 +++++-- 9 files changed, 20 insertions(+), 22 deletions(-) rename lib/alembic.ini => alembic.ini (97%) create mode 100644 lib/__pycache__/seed.cpython-38.pyc create mode 100644 lib/migrations/__pycache__/env.cpython-38.pyc create mode 100644 lib/migrations/versions/__pycache__/5f72c58bf48c_create_companies_devs.cpython-38.pyc create mode 100644 lib/migrations/versions/__pycache__/7a71dbf71c64_create_db.cpython-38.pyc mode change 100644 => 100755 lib/seed.py diff --git a/lib/alembic.ini b/alembic.ini similarity index 97% rename from lib/alembic.ini rename to alembic.ini index 953863ddd..fb1563a78 100644 --- a/lib/alembic.ini +++ b/alembic.ini @@ -2,7 +2,7 @@ [alembic] # path to migration scripts -script_location = migrations +script_location = lib/migrations # template used to generate migration file names; The default value is %%(rev)s_%%(slug)s # Uncomment the line below if you want the files to be prepended with date and time @@ -55,7 +55,7 @@ version_path_separator = os # Use os.pathsep. Default configuration used for ne # are written from script.py.mako # output_encoding = utf-8 -sqlalchemy.url = sqlite:///freebies.db +sqlalchemy.url = sqlite://lib/freebies.db [post_write_hooks] diff --git a/freebies.db b/freebies.db index 15fa3c476ffd76a8a0c2e40a5180d685d1358220..1d076dade58cba31f53cfe328a993dd9461410bd 100644 GIT binary patch delta 518 zcmZo@U~E{xI6<0~oq>UYb)tg3C_95*Stl?54+a)KDF%LC{+)dFd{Ubg1(xxOC$q4N zi;6NfYL+A><)o&hmKB3A>tq%F00m}tad~;h##FFWa(-?>VqRuyF`U6Nc?y3{eWNBL zySTPCV-qJ>Sz=CVZc=7)d|7Hyab|uV8kfmA$kj2#RUyRD$;VXzO;SOFixa9XKCd)a zAvVYBMrq=B1=o6c^@XmZZifmX_p$`SED(i8n+OUS8tfa7rf8qpZDLzIfRns(cqhwQyq%;$YWG=Xx&58<(K}ux!nN>NFm4J+4 z;=cnlhW`#!k?!O>@*;A4j4TYYOd+Ys8P54d1?*Qr3YqyIGw^@of5-nAs?+p&p@btR>WpsIRHrAFdqKB&j@+zQ>*hN!oMSoOqK+-o_<&X#Rn&dwHW9!L3%ne=KrUo6}6 zw!@1{WnO$(C|u(*9ExVecbkGg$~w7wStkm1+(ui(()E_7V`}Mp|PEdHz~uTez*0kMi_sEcT9QY?rWI_JzG= z`)vQbFCp>}fB*y_009U<00Izz00bZa0SNqsz*VY|+e+T=c-64ICI90HHbu(~y}&oV zr4t&tsXP%i_vt|5LrT-gv~pK;N&jQ}%raz#nf1-H5(LgP>w(RDIL30-WjnF%tQ(8&a)w0ym^?zO_pS|X+C sWcmUjrO=ZzT6|ef>}p($O)jZAnW9NL>#gz4h8qf1NzrIhGI?^+Z+%1ui2wiq diff --git a/lib/__pycache__/models.cpython-38.pyc b/lib/__pycache__/models.cpython-38.pyc index 543ccbc2dd06921c1f46b2fbb1c27860d49f03bb..8cb60bd50f3fddb66fee5ec555a260d0e16b7800 100644 GIT binary patch delta 19 ZcmdnNzk{DEl$V!_0SNXl-^jI&9RM!k1n2+& delta 19 ZcmdnNzk{DEl$V!_0SL~|+{m?#9RM!;1nK|) diff --git a/lib/__pycache__/seed.cpython-38.pyc b/lib/__pycache__/seed.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d1a9497b1ef5ed842e4a3d16ed9ab622d981fa3c GIT binary patch literal 1005 zcmY*YOK;Oa5Z;GhaUI&CBJmJXIr@-TZN&v41Qhi~g_Lr!gd)egiML(bVeM2(jY>AHa!Or&Y^ZJ3IS%{msm`@D916z#wU{GG^VXjrIp*Uojb9UyRnNAr_5qDb5|ltrGLaRvKss(4cKAulGP;33uSVVO^pVy@{sey-gk#ra6^ z#e?dz6g7VlMbUT-Red%(0tSnxS!vdhC|GL3+zb~S2j(Hn>Iaw_N@Il469Bx>k`BO#JWVV+N{I;2Aw($Id#~^%34~01+3d(!00t* z19p#Xw&!jzr)9MoyKyG;KTelzU9^IOSlh?3cLG%%mTD?~K@}mud5Bd9>W%5!aLSo4Mw}y7p`46IZUL~4g|_Yt<2SE0@3WL5=9-lF-i9{N%v#I_F(R7GKT#a z_Tz(}NIin{e?LW8ne*tBGr>fXMUW_$Mn X-bPj4eN6t|Pf%w&=#ZJ{fWI9OatB$Snq_JYuAX%{3As-ScQ8X=9G@k`>Y$CI@^ z?H0jlIdEAa@d;XS;w#OS6JG&=#Iw_E3rKim`}sY;|3A-@ot=!}`1F?t%Wo1we)EUB zql1S>IPK542qLH=70oI2bVqfnZr%-a7wIUE0v)Md73XoFdn&2YJPmZL`c;-^lt8>1 z*&Mf>5Gk*!8}t*kt-_bHT|Br&Z_$zagpeVu81TRy_cB0>s3E!z=496|_CgD-e^Y?V_k1J8l->iV7ST-0^ltNe70jVkWh)?NCUrpmasOcJ^eF zwDG3y?Ko(0sl5cdWqJsMw*RUtX5i0zGeEc%&Twsc>F>28)9B*1$rEb)L;IDO*Kqse zK*`ztTj_n!=hO9Nd+(o0#SJRnMisk{3mIlKqMh)?f5u5h%>i=%16uDYfc7yG9<&I` z_wIm}iq1=XxBmy%JHRCf-0sQQq}yhgx5hI0LWIP}2DAWEa9hl{E0>eR;9rD<7v?X9 za+zIZh5KgDQ$7={$30K`YHXI*k!lbAT>$N0#rr6--Uy+u^8YK2G5a@>H`&ies$O6N z7Sl~%jQ?x3*)2Rw7a1n<+ywhv&14xO%QNi5)IT|8O^o6^^$d%M4tbc7SJ~ZIE&Ly* z@UUvrEsi!>`5uH&+Of3TrWM}oo%}+kA<6Uu6g3JS`u~f43zuPMNW-MVIF2%!C2^X* Kkq%RucK!w;5PFgT literal 0 HcmV?d00001 diff --git a/lib/migrations/env.py b/lib/migrations/env.py index c7aab9656..49698f500 100644 --- a/lib/migrations/env.py +++ b/lib/migrations/env.py @@ -4,6 +4,10 @@ from sqlalchemy import pool from alembic import context +from lib.models import Base +from lib.seed import engine + + # this is the Alembic Config object, which provides # access to the values within the .ini file in use. @@ -18,7 +22,7 @@ # for 'autogenerate' support # from myapp import mymodel # target_metadata = mymodel.Base.metadata -from models import Base + target_metadata = Base.metadata # other values from the config, defined by the needs of env.py, @@ -27,7 +31,7 @@ # ... etc. -def run_migrations_offline() -> None: +def run_migrations_offline(): """Run migrations in 'offline' mode. This configures the context with just a URL @@ -51,22 +55,12 @@ def run_migrations_offline() -> None: context.run_migrations() -def run_migrations_online() -> None: - """Run migrations in 'online' mode. - - In this scenario we need to create an Engine - and associate a connection with the context. - - """ - connectable = engine_from_config( - config.get_section(config.config_ini_section), - prefix="sqlalchemy.", - poolclass=pool.NullPool, - ) - - with connectable.connect() as connection: +def run_migrations_online(): + with engine.connect() as connection: context.configure( - connection=connection, target_metadata=target_metadata, render_as_batch=True, + connection=connection, + target_metadata=target_metadata, + render_as_batch=True, ) with context.begin_transaction(): diff --git a/lib/migrations/versions/__pycache__/5f72c58bf48c_create_companies_devs.cpython-38.pyc b/lib/migrations/versions/__pycache__/5f72c58bf48c_create_companies_devs.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7464309476c3f5eb0f7fa7504399ba46b48f98fa GIT binary patch literal 1070 zcma)5OK;Oa5cVs!<0hz-3UQ3YDH5skY)XU>QYu7+R3Qo%U#yLHlDODwch@NjN5r)k z&K#N}e`&9r_zMUGTvaA2(+&&=+8-ub@u+h)^IaO{2_E`RHa@+}Xx2j-M#IK>Mz zRPhw5QY}(r&C}G}*CX9CsNvOU%`>U)SvYN~Q}c^TEoy%(_-Tt7{9dvr5R&O-v9!~n*gU7?+=;+XKzGDMQTa{Xpo_dXKWUsM}h+9k! z*^09uuhqhCr!>^f?~hW~(S7vk0WYNDOaebDpdi4cWq91L4xhd2U-= z!yaU#l)=x60!Ltpd6sc3miw=G7!$sJ3F~RXM8-+Tvabr?MV!L? zxN?_C4DLD5kcMRG;)ftg(im9g1_=c>T@nF9#p5F}NZj0wv9o+EX=lva|YiX@gETwQSSL{9-MKjgC;<0}k zX6f6%_#UqOC3Sx93#lKVQ%b#2E3r_xN&x+o*KwU2XxdsysY7{^mW1ANQ+juCo2=91 zJu43O5JQodDw?D6eSEifq~-fG34C8#B!YMr1{JEfh)5JHAzt$x+$n8d{V1}T1Nyh& zj1v|teY^t@3F%Nsfl=Wntmw4(&OZ-kKZz5%ir}e=_#&6puo|ju7;5q8cXs~(r+XGr literal 0 HcmV?d00001 diff --git a/lib/migrations/versions/__pycache__/7a71dbf71c64_create_db.cpython-38.pyc b/lib/migrations/versions/__pycache__/7a71dbf71c64_create_db.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6f54eedf7f8383974c5984eeda3cb314d8aafac1 GIT binary patch literal 705 zcmah`y>8nu5T<@?$!c5#=+ITG2SrvKIe<|V1(Km%GBgNKXb~vgB~nZMl$2e#TY)}7 z=e|H*iEF36LZ_bO6xP-w?!$fL@%Y{GZa()I+3Amq;?7{~S5L-f5qU$d-Vy*y7#Ls* zqcRiI=wnM*i4Ar#0V|o3JLE1{F!^b~6rAsNGJ9e!%!qkl-Li%E^+PU^cj!ardGB#o zsecYU6uXhxBW@v+>WD=c{133ZmGL;>|MN#PL}it=Fr_ z^L~>~wlK8Wv^V->T#YuT61%Oe^FC*6)H%B%S2h8#TlQ$&JTf^Yc7#9Q!lJ1#{D@FO z$%_zhhoWgKth+F80K>N63RgoMj&E1cSTbN?JBsJh*^n2Cwcw}WhlxltjY(; zJL+DAJCywxR5(_h9tM>{cGm8-vu!CI@I^1yBw&Vg3IE@boKV`anNj4>fu2G0r5;MZ zB>J!PjN-*J?W8F*d75g63#_s-m;KY)Q=bJFd4bhln~G~!K7FK~_tnxP%_Oh$A{9JC up|l6sVht*7>Os8hpBV`n#y+TWUsVlk1-|Y-NSzYc&WYjLwlOU0x&0R>OsB&D literal 0 HcmV?d00001 diff --git a/lib/seed.py b/lib/seed.py old mode 100644 new mode 100755 index 9eadaaad8..b40f9ab0f --- a/lib/seed.py +++ b/lib/seed.py @@ -3,11 +3,11 @@ from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine -from models import Company, Dev, Freebie, Base +from models import Company, Dev, Freebie # Create engine and session -engine = create_engine("sqlite:///freebies.db") -Base.metadata.create_all(engine) +engine = create_engine("sqlite:///freebies.db", echo=False) +# Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) session = Session() @@ -36,5 +36,9 @@ def seed_data(): print("Seed data added successfully!") + + + + if __name__ == "__main__": seed_data() From 0ec6a1ea12bf9539a5586b4500f4b365155125a8 Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Wed, 28 May 2025 18:15:04 +0300 Subject: [PATCH 20/23] Initiate migration to include the freebies table --- freebies.db | Bin 20480 -> 24576 bytes lib/__pycache__/seed.cpython-38.pyc | Bin 1005 -> 1043 bytes lib/migrations/__pycache__/env.cpython-38.pyc | Bin 1443 -> 1443 bytes .../99787e66492d_add_freebie_table.py | 37 ++++++++++++++++++ ...87e66492d_add_freebie_table.cpython-38.pyc | Bin 0 -> 1197 bytes lib/seed.py | 16 ++++---- 6 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 lib/migrations/versions/99787e66492d_add_freebie_table.py create mode 100644 lib/migrations/versions/__pycache__/99787e66492d_add_freebie_table.cpython-38.pyc diff --git a/freebies.db b/freebies.db index 1d076dade58cba31f53cfe328a993dd9461410bd..d1b5d19a7b0c13a692dc6edbf3ff46923c65f86a 100644 GIT binary patch delta 844 zcmaKpKWGzC7{K4k_%}P za7rUObW`Hy;v%>>Xa}_jx>{Tu1T6&zcXbeP^rgL|Om1o!WPU~078f#PNn4E`2{EE; z^O~+@(pr`r;+`C}in0GRU}H?NIdW_tE_^uOP|*XYSI-yQp1^wnIhmZfJVO(S>Exy2 zOY$4y$AQA$-w(40e!)I`gxBy49>G1R!A)3(S%_{2#=_9XegQ>X1}&_o?Rri69P|n3 zylalOvUa)IuSTj^`9d8gax^9QTML2*AHR^z91fUdoTVCcG*mCAtCc38s|9fTJx6AkJ&Gg*aDY` bCOO0z7qaVCy>SL(PDCMQWox!w<^9S(g1q4P delta 158 zcmZoTz}T>Wae}lUI|Bm)D-go~^F$qEQFaEsvQA$99}FyfQVjgO{5$#T`J^@r3M}K@ zEX8+AkjFI5+$h=9A}P(pB6*X-7k&w30bZa{O#F8k_&@O90qVKHKlzTm1{X8`V+Q_j r{O|Z51I4cL%W^U^Gf0Lfrj_O-vN16;2s`B`aWFD7h&$$FCZ_@b`0FN1 diff --git a/lib/__pycache__/seed.cpython-38.pyc b/lib/__pycache__/seed.cpython-38.pyc index d1a9497b1ef5ed842e4a3d16ed9ab622d981fa3c..a3b2a39150df7cf6f611d37d72edbe3bf426a948 100644 GIT binary patch delta 103 zcmaFMKAD3%l$V!_0SIi>%qMcoGbT;c4i-t}N#V+7DvC?xZf0O)NZ}4<(B#?Ja-E6y z7Ds%1ZenI$e7v6~@8me<7%q@VUSe))eEj5H%*rAHK$CbFd6-0)d6>Bv*_b$FI2Zv4 CC>IF; delta 64 zcmbQt@s^!Cl$V!_0SMkLHl4^V&loaMJD4qnE0{r(d*h_*Ow4|oJd?|qV 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/migrations/versions/__pycache__/99787e66492d_add_freebie_table.cpython-38.pyc b/lib/migrations/versions/__pycache__/99787e66492d_add_freebie_table.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d7abfd6dee121b6976a6420711217ea4c58e9e6a GIT binary patch literal 1197 zcmZuw&2HO95ayB;Nzt-hG;WjJh#m^)Ak&c}TNa9NQGb?htcwWq#8(Nl*M9VrvjnUt` z5eYyrSBNu?L6yt|`u@*&%}buk;N`PPaB*=yKF71Orx!!mo?tl%M)UJwIvUUBPsgc0 zRhU#5JR>p*h9|?(;AAuyj)N!T$;oJPdT~5HIU5h3`2OFNyU}Ob%!|vYx9eH=c0H1c zqp(^jnbsD&>yU&g?edmLW!y4gmHE~Jvode(jX`&`f43T>Lr8}Z=Of~_I`@e81=9Tt zall(J@E43?xv;lk&};lV&?S7o#SiZATMx_)+jOZX2G#fQQhRN2OKoy^PB-)9N{G79 zy2~rfVwq(4i|$+}VujjI^Q=hZI_97qz-#*7^tKqs@|Z&u%&+1*m+`%J%aRg>uxp<; zF4;FG4|h$rPUHHl-&H16QTNiOfpOD*ZI+34rny*UQoAo@g$q>Lc~dDa7y9UVu8=R} zD_l==Syn3HveIm>k6tUDC2IZ2!Jmfuh5|I?-`~Pzo?-YFfdfyLA!UFfFEW%>nC5_C zu}n%lZTLaDOoTwWAaq?Vb2%tZ2kor~6g0g;6$(BJGrmwsMYCFl*Qn~DEyLZpifO#> z%C)`Uak19!svtAK2b5fSM8q&1_Vvf_5qreEf7C<5znH)J9X9iKK+JajHmvQod8s;t z_RVcseNcI^4SHXOE%z;{=`Q5&Ws}EuB$jn63{yQO+TYV|97CSQv33)I*^H;H&+?r} zM7qRmt?CT4r`pG=_iK0Yy*N{eOqVf@8j4c;fCWk@<6JfuYvTNGTHX&?4l98_GV))3 QMZ|V{%(HFQeAdC?f7M_`fB*mh literal 0 HcmV?d00001 diff --git a/lib/seed.py b/lib/seed.py index b40f9ab0f..1368f69ad 100755 --- a/lib/seed.py +++ b/lib/seed.py @@ -5,32 +5,32 @@ from models import Company, Dev, Freebie -# Create engine and session + engine = create_engine("sqlite:///freebies.db", echo=False) -# Base.metadata.create_all(engine) + Session = sessionmaker(bind=engine) session = Session() def seed_data(): - # Create some companies + c1 = Company(name="TechCorp", founding_year=2005) c2 = Company(name="DevSolutions", founding_year=2010) - # Create some devs + d1 = Dev(name="Alice") d2 = Dev(name="Bob") - # Add companies and devs to session + session.add_all([c1, c2, d1, d2]) - session.commit() # Commit to generate ids for FKs + session.commit() - # Create freebies linked to companies and devs + f1 = Freebie(item_name="Sticker Pack", value=0, company_id=c1.id, dev_id=d1.id) f2 = Freebie(item_name="T-Shirt", value=20, company_id=c2.id, dev_id=d2.id) f3 = Freebie(item_name="Mug", value=10, company_id=c1.id, dev_id=d2.id) - # Add freebies and commit + session.add_all([f1, f2, f3]) session.commit() From c7e9aad1d51a759fbcdf1d770d65293d6221e799 Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Wed, 28 May 2025 18:39:05 +0300 Subject: [PATCH 21/23] Define a secondary relationship on the freebie model --- Pipfile | 2 +- Pipfile.lock | 153 ++++++++++++++++---------- lib/__pycache__/models.cpython-38.pyc | Bin 1976 -> 1976 bytes lib/__pycache__/seed.cpython-38.pyc | Bin 1043 -> 1037 bytes lib/debug.py | 8 +- lib/models.py | 7 ++ 6 files changed, 111 insertions(+), 59 deletions(-) mode change 100644 => 100755 lib/debug.py diff --git a/Pipfile b/Pipfile index 63c79cd98..c5b7f4dcb 100644 --- a/Pipfile +++ b/Pipfile @@ -7,8 +7,8 @@ name = "pypi" alembic = "1.8.1" importlib-metadata = "6.0.0" importlib-resources = "5.10.0" -ipdb = "0.13.9" sqlalchemy = "1.4.42" +ipdb = "*" [dev-packages] diff --git a/Pipfile.lock b/Pipfile.lock index 3923f4a97..a47c681b2 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "fa62c636b7ae5acb4993fc7b007a651c55b562aa29962a9a8585ec314b352ae6" + "sha256": "932bb367ba9b55f09db8822137fe32f19ecfa9cb8dd7ed234933e266fe50f909" }, "pipfile-spec": 6, "requires": { @@ -34,10 +34,11 @@ }, "asttokens": { "hashes": [ - "sha256:4622110b2a6f30b77e1473affaa97e711bc2f07d3f10848420ff1898edbe94f3", - "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c" + "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", + "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2" ], - "version": "==2.2.1" + "markers": "python_version >= '3.8'", + "version": "==3.0.0" }, "backcall": { "hashes": [ @@ -48,18 +49,19 @@ }, "decorator": { "hashes": [ - "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330", - "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186" + "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360", + "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a" ], - "markers": "python_version < '3.11' and python_version >= '3.7'", - "version": "==5.1.1" + "markers": "python_version >= '3.8'", + "version": "==5.2.1" }, "executing": { "hashes": [ - "sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc", - "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107" + "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa", + "sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755" ], - "version": "==1.2.0" + "markers": "python_version >= '3.8'", + "version": "==2.2.0" }, "importlib-metadata": { "hashes": [ @@ -79,27 +81,28 @@ }, "ipdb": { "hashes": [ - "sha256:c23b6736f01fd4586cc2ecbebdf79a5eb454796853e1cd8f2ed3b7b91d4a3e93", - "sha256:f74c2f741c18b909eaf89f19fde973f745ac721744aa1465888ce45813b63a9c" + "sha256:45529994741c4ab6d2388bfa5d7b725c2cf7fe9deffabdb8a6113aa5ed449ed4", + "sha256:e3ac6018ef05126d442af680aad863006ec19d02290561ac88b8b1c0b0cfc726" ], "index": "pypi", - "version": "==0.13.11" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.13.13" }, "ipython": { "hashes": [ - "sha256:da01e6df1501e6e7c32b5084212ddadd4ee2471602e2cf3e0190f4de6b0ea481", - "sha256:f3bf2c08505ad2c3f4ed5c46ae0331a8547d36bf4b21a451e8ae80c0791db95b" + "sha256:3910c4b54543c2ad73d06579aa771041b7d5707b033bd488669b4cf544e3b363", + "sha256:b0340d46a933d27c657b211a329d0be23793c36595acf9e6ef4164bc01a1804c" ], - "markers": "python_version < '3.11' and python_version >= '3.7'", - "version": "==8.8.0" + "markers": "python_version >= '3.8'", + "version": "==8.12.3" }, "jedi": { "hashes": [ - "sha256:203c1fd9d969ab8f2119ec0a3342e0b49910045abe6af0a3ae83a5764d54639e", - "sha256:bae794c30d07f6d910d32a7048af09b5a39ed740918da923c6b780790ebac612" + "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", + "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9" ], "markers": "python_version >= '3.6'", - "version": "==0.18.2" + "version": "==0.19.2" }, "mako": { "hashes": [ @@ -167,27 +170,27 @@ }, "matplotlib-inline": { "hashes": [ - "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311", - "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304" + "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90", + "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca" ], - "markers": "python_version >= '3.5'", - "version": "==0.1.6" + "markers": "python_version >= '3.8'", + "version": "==0.1.7" }, "parso": { "hashes": [ - "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0", - "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75" + "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18", + "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d" ], "markers": "python_version >= '3.6'", - "version": "==0.8.3" + "version": "==0.8.4" }, "pexpect": { "hashes": [ - "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937", - "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c" + "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", + "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f" ], "markers": "sys_platform != 'win32'", - "version": "==4.8.0" + "version": "==4.9.0" }, "pickleshare": { "hashes": [ @@ -198,11 +201,11 @@ }, "prompt-toolkit": { "hashes": [ - "sha256:3e163f254bef5a03b146397d7c1963bd3e2812f0964bb9a24e6ec761fd28db63", - "sha256:aa64ad242a462c5ff0363a7b9cfe696c20d55d9fc60c11fd8e632d064804d305" + "sha256:52742911fde84e2d423e2f9a4cf1de7d7ac4e51958f648d9540e0fb8db077b07", + "sha256:931a162e3b27fc90c86f1b48bb1fb2c528c2761475e57c9c06de13311c7b54ed" ], - "markers": "python_full_version >= '3.6.2'", - "version": "==3.0.36" + "markers": "python_version >= '3.8'", + "version": "==3.0.51" }, "ptyprocess": { "hashes": [ @@ -213,18 +216,18 @@ }, "pure-eval": { "hashes": [ - "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350", - "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3" + "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", + "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42" ], - "version": "==0.2.2" + "version": "==0.2.3" }, "pygments": { "hashes": [ - "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297", - "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717" + "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", + "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c" ], - "markers": "python_version >= '3.6'", - "version": "==2.14.0" + "markers": "python_version >= '3.8'", + "version": "==2.19.1" }, "six": { "hashes": [ @@ -283,33 +286,71 @@ }, "stack-data": { "hashes": [ - "sha256:32d2dd0376772d01b6cb9fc996f3c8b57a357089dec328ed4b6553d037eaf815", - "sha256:cbb2a53eb64e5785878201a97ed7c7b94883f48b87bfb0bbe8b623c74679e4a8" + "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", + "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695" ], - "version": "==0.6.2" + "version": "==0.6.3" }, "tomli": { "hashes": [ - "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", - "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" + "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", + "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", + "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", + "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", + "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", + "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", + "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", + "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", + "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", + "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", + "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", + "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", + "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", + "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", + "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", + "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", + "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", + "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", + "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", + "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", + "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", + "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", + "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", + "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", + "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", + "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", + "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", + "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", + "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", + "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", + "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", + "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7" ], - "markers": "python_version < '3.11' and python_version >= '3.7'", - "version": "==2.0.1" + "markers": "python_version >= '3.8'", + "version": "==2.2.1" }, "traitlets": { "hashes": [ - "sha256:32500888f5ff7bbf3b9267ea31748fa657aaf34d56d85e60f91dda7dc7f5785b", - "sha256:a1ca5df6414f8b5760f7c5f256e326ee21b581742114545b462b35ffe3f04861" + "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", + "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f" ], - "markers": "python_version >= '3.7'", - "version": "==5.8.1" + "markers": "python_version >= '3.8'", + "version": "==5.14.3" + }, + "typing-extensions": { + "hashes": [ + "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", + "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef" + ], + "markers": "python_version >= '3.8'", + "version": "==4.13.2" }, "wcwidth": { "hashes": [ - "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e", - "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0" + "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", + "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5" ], - "version": "==0.2.6" + "version": "==0.2.13" }, "zipp": { "hashes": [ diff --git a/lib/__pycache__/models.cpython-38.pyc b/lib/__pycache__/models.cpython-38.pyc index 8cb60bd50f3fddb66fee5ec555a260d0e16b7800..6c358d1939d4a37931ae0c82edfab3f796bb918a 100644 GIT binary patch delta 532 zcmdnNzk{DUl$V!_0SE-u%{OvCWMqt*{FYGMSLJh0gx_cpg@rj zkTqGG$v}sY&DTwbI&`4DT8D0Zh>vZ>S)>r`csVJaYk2}ne7CFkcBB<5AdXQo840fPxhLp&k~ zQlbPRaQX)1P<0?K20C!^9X1h0fyp1)w1E*R%kHff#p0A$oLa;SG6Cdma7-YDGB~^? JC-<>y0RVvzS=ayo delta 532 zcmdnNzk{DUl$V!_0SNXlH{Hnnkdg7$6LY4bx={aiHui-n9JEyp+tm z^!Uou#G)d0kQhf=QEF;ZW@>Sf43JwSg-S?IZf9rV#1E1b1nFW13KR(g zS(CMy4AfX{TvE#vibO%uVjw~SL?Dck261I3SF6hQ^xOK(&+au!%4VPX5TI4U9-xc5k&?EKZ5VsYSdX6F}Yu#{^O+gTq^T Iav!@E0M3bDga7~l diff --git a/lib/__pycache__/seed.cpython-38.pyc b/lib/__pycache__/seed.cpython-38.pyc index a3b2a39150df7cf6f611d37d72edbe3bf426a948..e02dcfd9fd90bfa92024dd782ef8fd394068bfff 100644 GIT binary patch delta 190 zcmbQt(aXUX%FD~e00fWK%rmAlZ{$14$QU*G2BW8Z6lZ2hYHoa9Vs7d!*0RK$($pxf zFKP5G%xQGQPUBn6^*gy)|QuER?^HQVOgHwx(GxPI`ctKJyGeEY-#}|QY MKq5pZzhzbf0I63rk^lez delta 172 zcmeC>n9RW!%FD~e00g#b<{5n~8~IK$GTxeegV9s|7H4KjYHoa9Vs7d!*0RK$($rgA z$@#ejiFuXrnJKp>J1_+URZd}YWRnDH{}ns=Hd6qj-efIiOCf2Xz%7pW_}s+Iy!d!O zP2O9ROPSSJxpFd-^d`??mesq(9-LZSoSC0jBnVVm1XB;PD?YvmWF8VBHTgNS8UP+A BGZFv* diff --git a/lib/debug.py b/lib/debug.py old mode 100644 new mode 100755 index 4f922eb69..6c9991c1d --- a/lib/debug.py +++ b/lib/debug.py @@ -1,9 +1,13 @@ #!/usr/bin/env python3 from sqlalchemy import create_engine +from seed import engine,session -from models import Company, Dev +from models import Company, Dev,Freebie + + +print("\n Interactive Debug Mode. You can now test your models.") if __name__ == '__main__': - engine = create_engine('sqlite:///freebies.db') + import ipdb; ipdb.set_trace() diff --git a/lib/models.py b/lib/models.py index 3be3efd0b..8fd57a51f 100644 --- a/lib/models.py +++ b/lib/models.py @@ -32,6 +32,13 @@ class Dev(Base): # relationships freebies=relationship("Freebie", back_populates="dev") + companies=relationship( + "Company", + secondary="freebies", + back_populates="devs", + viewonly=True + ) + def __repr__(self): return f'' From e6ab6a069311d2bc424053e7c3e42f030991c462 Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Wed, 28 May 2025 18:54:29 +0300 Subject: [PATCH 22/23] Fix code issues --- freebies.db | Bin 24576 -> 24576 bytes lib/__pycache__/models.cpython-38.pyc | Bin 1976 -> 2095 bytes lib/models.py | 7 +++++++ lib/seed.py | 2 +- run.py | 5 ++++- 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/freebies.db b/freebies.db index d1b5d19a7b0c13a692dc6edbf3ff46923c65f86a..2657abe9854d557786501abc8e7ff01b1f8aad08 100644 GIT binary patch delta 254 zcmZoTz}Rqrae_3X*hCp;MzM_vOZ4S<`6U?mKk(n-Kf}L+e+B;({ucfM{sev>ej9!r zeu>S30^j&lgm_sPRGC~-%YyTBN=q{H^NQJT@$s-Q$TEebCTBS37ZtEyoor)&f?0q+ ze=@s+EDL`*e?CyFJHHT{05gNIQ+^T$KQn{4V@_sr>f}cM20;b}23G#XO#JuxPxEi( zU(EjjsCpuQtN<$;gES)}V~B2WMrKio2(N$$3mbzf2P0!}NoI0(YLP-fVsbVQzYsGU qgFH~3Z+>ZUszO0x3KusYKNCnV16(g34;veUFi25pIv0-s0|NjF#yije delta 148 zcmZoTz}Rqrae_3X&_o$$Mxl)fOY~*9`E3~ZKk(n-Kf}L+e+B;({ucfM{sev>ej9#` z&4L0l{F80$PcZZGH%?}EkOd0F@=tE`Z{X#>!NAOa3Z(Ns|0$sG9)2?(W;O<4Mn*>8 v(sV9vJ_ZH`b|B_wVq=hIWMB-@4bI3cDiPu1V`O6x2dWA#$j{GX=H>+ekz68? diff --git a/lib/__pycache__/models.cpython-38.pyc b/lib/__pycache__/models.cpython-38.pyc index 6c358d1939d4a37931ae0c82edfab3f796bb918a..fe04fe4353e6e6ada2b721485e641c11cdacc7f1 100644 GIT binary patch delta 835 zcma))J#P~+7{_D#-g3FSHf;l>(Dq78n>G?J17d(myh#jn02LUzM3=J*5$RoIw?UDR z!oUg=^1{FuU_xxnd<=gBBpBEkc%Dn7C`gg;$-nbsKeC_y-~KlDWj=ZuhJFcJ{mP9O zkKM1)8{#_<-iEH8>5pWuA$;y~j}uOL`JHtbaGzJ+mJUN69F%rK}Eo$PsQAQCBEn3HF4!Q!H?p8CT9DRuB^v>57oL}xAOp%6;eQ{{$$5aA+V;u+wJ-+33v3K z6A%Aaz%HK9L{Nb7)6pwyb+~cBQTUJKEnvzHV&)^jVy{D2kXu82Bp@E~;4MTnAOV$C k{o830qgULATgJMZC^5RL;yw$hlN%{Uv3~Dvv&H$PzZ3wHUjP6A delta 740 zcma)(O-lkn7=WGK)wOMRTP;ibv=1_gB=QhNr;IuTU8>7;SXOsR$y8=5&`TXU1RWwK zqJI%VP{)3U|0U>sS2GKO7UtRceBXKIeX`#A%zeYq0`Nsr%f(#i*}Np;HrPWpg|5tr zcM^-csvEuvP~Gj>4WzZEnya4FoJyUF50bH{nRg1ucCA`FD?6vm6F17Dc#x7LE?%W_ zatH!@5{4%Yt9>wI+nm+7ZSSNFk(0L$Vz5k&!|GYZEme-}I&(NzVXhfISdjcAfC`74FHNP?_^Np`+%(c89=H`qBP0_J4j={*-?{y?c%Nx#Uv4^t>+;h12p$?mj3LGmGD1O2Ac6>V_hoq!dmYb( z-x()i8CN|lR$EjCO`Jzf@ffTwp@bi(CDqUiey!jIGbOj7qAqm&r{PiDJ1JH|`NUs_ zS@9A|Ui?=D--FK}u;5f{<*wT$mxdrS{9B?C+%kpe*#4G9j}$ZyE-7}^0b+@wI!~y$ dSGQ-WvhH}SC4u&S>AE8LrAmlkI3??r@d=%7hsgi{ diff --git a/lib/models.py b/lib/models.py index 8fd57a51f..2062a8983 100644 --- a/lib/models.py +++ b/lib/models.py @@ -20,6 +20,13 @@ class Company(Base): # relationships freebies=relationship("Freebie", back_populates="company") + devs=relationship( + "Dev", + secondary="freebies", + back_populates="companies", + viewonly=True + ) + def __repr__(self): return f'' diff --git a/lib/seed.py b/lib/seed.py index 1368f69ad..87393d97d 100755 --- a/lib/seed.py +++ b/lib/seed.py @@ -34,7 +34,7 @@ def seed_data(): session.add_all([f1, f2, f3]) session.commit() - print("Seed data added successfully!") + print("Seed data added successfully! 🌱") diff --git a/run.py b/run.py index 2db0d1166..7edb16c20 100755 --- a/run.py +++ b/run.py @@ -328,7 +328,9 @@ def main(): choice=input("Select and option: ") if choice == "0": - print("Goodbye!") + print( + "-----------------------------------------------\nThank you for visiting us. Welcome again!\n------------------------------------------------" + ) break action=cli_actions.get(choice) @@ -336,6 +338,7 @@ def main(): action() else: print("Invalid option. Try again.") + print("*************************************************************") if __name__ == "__main__": main() From 698b6e45aeef06f533c8bce9bffeb91520bb5d2e Mon Sep 17 00:00:00 2001 From: jedaqsaul Date: Wed, 28 May 2025 19:10:09 +0300 Subject: [PATCH 23/23] Adds readme file --- README.md | 198 +++++--------------------- freebies.db | Bin 24576 -> 24576 bytes lib/__pycache__/models.cpython-38.pyc | Bin 2095 -> 2077 bytes lib/debug.py | 2 +- lib/models.py | 2 +- run.py | 2 +- 6 files changed, 36 insertions(+), 168 deletions(-) diff --git a/README.md b/README.md index b598b7784..26820e2e5 100644 --- a/README.md +++ b/README.md @@ -1,182 +1,50 @@ -# Phase 3 Mock Code Challenge: Freebie Tracker +# Freebie Tracker -## Learning Goals +This is a simple Python CLI project using SQLAlchemy to track developer freebies from companies. It includes database migrations with Alembic and supports basic CRUD operations via CLI. -- Write SQLAlchemy migrations. -- Connect between tables using SQLAlchemy relationships. -- Use SQLAlchemy to run CRUD statements in the database. +## Project Structure -*** +python-p3-freebie-tracker/ +├── config/ +│ └── setup.py +├── db/ +│ └── store.db +├── lib/ +│ ├── models.py +│ ├── seed.py +│ └── debug.py +├── migrations/ +├── run.py +├── alembic.ini +└── README.md -## Key Vocab -- **Schema**: the blueprint of a database. Describes how data relates to other - data in tables, columns, and relationships between them. -- **Persist**: save a schema in a database. -- **Engine**: a Python object that translates SQL to Python and vice-versa. -- **Session**: a Python object that uses an engine to allow us to - programmatically interact with a database. -- **Transaction**: a strategy for executing database statements such that - the group succeeds or fails as a unit. -- **Migration**: the process of moving data from one or more databases to one - or more target databases. - -*** -## Introduction +## ⚙️ Setup -For this assignment, we'll be working with a freebie domain. +```bash +pipenv install +pipenv shell +alembic upgrade head +python lib/seed.py # Populate initial data +python run.py # Start the CLI + Features +Track freebies given by companies to developers. -As developers, when you attend hackathons, you'll realize they hand out a lot of -free items (informally called _freebies_, or swag)! Let's make an app for -developers that keeps track of all the freebies they obtain. +View companies, devs, and their associations. -We have three models: `Company`, `Dev`, and `Freebie` +Seed and debug scripts included for testing and development. -For our purposes, a `Company` has many `Freebie`s, a `Dev` has many `Freebie`s, -and a `Freebie` belongs to a `Dev` and to a `Company`. + ER Diagram +View the entity relationship diagram here: +https://dbdiagram.io/d/683732fbc07db17e77908287 -`Company` - `Dev` is a many to many relationship. -**Note**: You should draw your domain on paper or on a whiteboard _before you -start coding_. Remember to identify a single source of truth for your data. +- GitHub Repository +Source Code: +https://github.com/jedaqsaul/python-p3-freebie-tracker -## Instructions -To get started, run `pipenv install && pipenv shell` while inside of this -directory. -Build out all of the methods listed in the deliverables. The methods are listed -in a suggested order, but you can feel free to tackle the ones you think are -easiest. Be careful: some of the later methods rely on earlier ones. -**Remember!** This mock code challenge does not have tests. You cannot run -`pytest` and you cannot run `learn test`. You'll need to create your own sample -instances so that you can try out your code on your own. Make sure your -relationships and methods work in the console before submitting. -We've provided you with a tool that you can use to test your code. To use it, -run `python debug.py` from the command line. This will start an `ipdb` session -with your classes defined. You can test out the methods that you write here. You -are also encouraged to use the `seed.py` file to create sample data to test your -models and associations. - -Writing error-free code is more important than completing all of the -deliverables listed- prioritize writing methods that work over writing more -methods that don't work. You should test your code in the console as you write. - -Similarly, messy code that works is better than clean code that doesn't. First, -prioritize getting things working. Then, if there is time at the end, refactor -your code to adhere to best practices. - -**Before you submit!** Save and run your code to verify that it works as you -expect. If you have any methods that are not working yet, feel free to leave -comments describing your progress. - -*** - -## What You Already Have - -The starter code has migrations and models for the initial `Company` and `Dev` -models, and seed data for some `Company`s and `Dev`s. The schema currently looks -like this: - -### companies Table - -| Column | Type | -| ------------- | ------- | -| name | String | -| founding_year | Integer | - -### devs Table - -| Column | Type | -| ------ | ------ | -| name | String | - -You will need to create the migration for the `freebies` table using the -attributes specified in the deliverables below. - -*** - -## Deliverables - -Write the following methods in the classes in the files provided. Feel free to -build out any helper methods if needed. - -Remember: SQLAlchemy gives your classes access to a lot of methods already! -Keep in mind what methods SQLAlchemy gives you access to on each of your -classes when you're approaching the deliverables below. - -### Migrations - -Before working on the rest of the deliverables, you will need to create a -migration for the `freebies` table. - -- A `Freebie` belongs to a `Dev`, and a `Freebie` also belongs to a `Company`. - In your migration, create any columns your `freebies` table will need to - establish these relationships using the right foreign keys. -- The `freebies` table should also have: - - An `item_name` column that stores a string. - - A `value` column that stores an integer. - -After creating the `freebies` table using a migration, use the `seed.py` file to -create instances of your `Freebie` class so you can test your code. - -**After you've set up your `freebies` table**, work on building out the following -deliverables. - -### Relationship Attributes and Methods - -Use SQLAlchemy's `ForeignKey`, `relationship()`, and `backref()` objects to -build relationships between your three models. - -**Note**: The plural of "freebie" is "freebies" and the singular of "freebies" -is "freebie". - -#### Freebie - -- `Freebie.dev` returns the `Dev` instance for this Freebie. -- `Freebie.company` returns the `Company` instance for this Freebie. - -#### Company - -- `Company.freebies` returns a collection of all the freebies for the Company. -- `Company.devs` returns a collection of all the devs who collected freebies - from the company. - -#### Dev - -- `Dev.freebies` returns a collection of all the freebies that the Dev has collected. -- `Dev.companies`returns a collection of all the companies that the Dev has collected - freebies from. - -Use `python debug.py` and check that these methods work before proceeding. For -example, you should be able to retrieve a dev from the database by its -attributes and view their companies with `dev.companies` (based on your seed -data). - -### Aggregate Methods - -#### Freebie - -- `Freebie.print_details()`should return a string formatted as follows: - `{dev name} owns a {freebie item_name} from {company name}`. - -#### Company - -- `Company.give_freebie(dev, item_name, value)` takes a `dev` (an instance of - the `Dev` class), an `item_name` (string), and a `value` as arguments, and - creates a new `Freebie` instance associated with this company and the given - dev. -- Class method `Company.oldest_company()`returns the `Company` instance with - the earliest founding year. - -#### Dev - -- `Dev.received_one(item_name)` accepts an `item_name` (string) and returns - `True` if any of the freebies associated with the dev has that `item_name`, - otherwise returns `False`. -- `Dev.give_away(dev, freebie)` accepts a `Dev` instance and a `Freebie` - instance, changes the freebie's dev to be the given dev; your code should only - make the change if the freebie belongs to the dev who's giving it away diff --git a/freebies.db b/freebies.db index 2657abe9854d557786501abc8e7ff01b1f8aad08..e86a4453421af3bb432a8f2573f0304382c63142 100644 GIT binary patch delta 50 zcmZoTz}Rqrae_3X_(U0JM)8daOYE5i`O_w|J18>or)?G#u;J%q7i4A-^-V0Q+??+} GQ2+p8V+}w6 delta 37 tcmZoTz}Rqrae_3X*hCp;MzM_vOYE5i`12>TJ1A}z6maL?obNwT007xt3kU!J diff --git a/lib/__pycache__/models.cpython-38.pyc b/lib/__pycache__/models.cpython-38.pyc index fe04fe4353e6e6ada2b721485e641c11cdacc7f1..d400a8238ac417a1a6660646be69a00bcb1b8c7d 100644 GIT binary patch delta 704 zcma)(zi-n(9L0V9k&ErS)}<*@p>0f?s!fqPAS6Tu9a!jugv1YF389d?ww4k*I@3yY zZHF!l(Jd_e2?zuO{{lOkH~svsQL`WI%@X>pBzUTM#eMvqg{5j{5W1g$K_l^(7 ze3e{`Z+A1|2uFB><}l1cqkR$NB#UGqBhmOkvRH;P7St&A*bz+;UN|C@?A*(^@sWs) zkFB3Go(XO|w|;*7?cqGBnUaIvySyx_<9zg;lBa|$>R0Y-vZjByzxHpMLNz}uPYRJ2 zM{nNCo>J7TsU>XqLY`JCgQ!>m*j|hsaYks} gd@wA<$w2NCbF9L9CGHRIi=otWEUZBOu>o2OMm3UXQ9Bqe#N-jSmG zp$%0AKrzu7Ka9mFL{WMTA1jr&T7^*gptYww9GC>GiC&C(K%&8X(T|lPa7{5NPxQIc zM~uUW5yZ>tKGsorulpNg7{?K1LN9yk}|sd4lL zJ=1wz?_;OdYP7><#N(NW9h-Oo5W4>9Nj&)}v+e!c`XW=Fd9U>pZagg?Gh^jGjMX=_ z^K#xSnJBwb&CAf7Q-vk}m_E