How to create two tables at the same time in FAST API - python

i want to create two tables at the same time. and also use one tables primary key to another tables foreign key at the same time.
def createOrderPlace(request: OrderCreatePlaceOrder, db: Session):
#try:
x = format(random.randint(10000,99999), '04d')
exists_x=db.query(OrderModel).filter(OrderModel.order_id == x).first()
if exists_x:
x = format(random.randint(10000,99999), '04d')
order_create = OrderModel(
user_id=request.currentUser.user_id,
name=request.currentUser.name,
email=request.currentUser.email,
orderAmount=request.subtotal,
cvv_id=request.currentUser.cvv_id,
card_name=request.currentUser.card_name,
card_number=request.currentUser.card_number,
card_month=request.currentUser.card_month,
card_year=request.currentUser.card_year,
order_id=x,
billing_first_name=request.currentUser.billing_first_name,
billing_last_name=request.currentUser.billing_last_name,
billing_phone_number=request.currentUser.billing_phone_number,
billing_country=request.currentUser.billing_country,
billing_division=request.currentUser.billing_division,
billing_district=request.currentUser.billing_district,
billing_address=request.currentUser.billing_address,
billing_police_station=request.currentUser.billing_police_station,
billing_post_code=request.currentUser.billing_post_code,
shipping_first_name=request.currentUser.shipping_first_name,
shipping_last_name=request.currentUser.shipping_last_name,
shipping_phone_number=request.currentUser.shipping_phone_number,
shipping_country=request.currentUser.shipping_country,
shipping_division=request.currentUser.shipping_division,
shipping_district=request.currentUser.shipping_district,
shipping_address=request.currentUser.shipping_address,
shipping_police_station=request.currentUser.shipping_police_station,
shipping_post_code=request.currentUser.shipping_post_code,
)
db.add(order_create)
db_orderid = (
db.query(OrderModel)
.filter(OrderModel.user_id == request.currentUser.user_id)
.first()
)
for dic in request.cartItems:
order_item_a = OrderItemsModel(
item_id=dic.item_id,
name=dic.item_name,
price=dic.item_price,
description=dic.item_description,
user_id=dic.user_id,
payment_order_id=dic.payment_order_id,
)
db.add(order_item_a)
db.commit()
return {'invoice':request,'detail': f'Successfully Buy this Service, Check it on My service','message':True,'order_number':order_create.order_id}
i tried this but thats not work. I am using two models
class OrderModel(Base): **(model 1)**
__tablename__ = "tbl_order_and_payment-order"
id = Column(Integer, primary_key=True, index=True)
name = Column(String)
email = Column(String)
orderAmount = Column(Integer)
transactionId = Column(String)
isDelivered = Column(Boolean)
user_id = Column(Integer, ForeignKey('tbl_stu_usr-users.id'))
purchase_date = Column(DateTime, default=datetime.utcnow)
#updated_at = Column(DateTime, default=datetime.utcnow)
cvv_id=Column(String)
card_name=Column(String)
card_number=Column(String)
card_month=Column(Integer)
card_year=Column(Integer)
order_id = Column(Integer)
billing_first_name=Column(String)
billing_last_name=Column(String)
billing_phone_number=Column(String)
billing_country=Column(String)
billing_division=Column(String)
billing_district=Column(String)
billing_address=Column(String)
billing_police_station=Column(String)
billing_post_code=Column(Integer)
i have another model
class OrderItemsModel(Base):
__tablename__ = "tbl_order_and_payment-order_items"
id = Column(Integer, primary_key=True, index=True)
item_id=Column(Integer, ForeignKey('tbl_stu_adm-pricing_plan-service.id'))
user_id = Column(Integer, ForeignKey('tbl_stu_usr-users.id'))
name = Column(String)
price = Column(Integer)
description=Column(String)
product_type=Column(String)
payment_order_id=Column(Integer, ForeignKey('tbl_order_and_payment-order.id'))
i am using "tbl_order_and_payment-order.id" this primary tho this "tbl_order_and_payment-order_items" tables as payment_order_id=Column(Integer, ForeignKey('tbl_order_and_payment-order.id'))
i just want to create two tables at the same time.

Related

Sqlalchemy: How to manage multiple tables (Python)?

I need to create four tables. First table include the "Users", second include "Group Name", the second table should be related to "Users" table. Third table include "Groups Columns Data" which is related to "Group" table, and finally the fourth table is "Group Borrow Lending Data" which is also linked to third table i.e "Groups".
But it's throwing an error when I try to get specific username.
TypeError: sqlalchemy.exc.InvalidRequestError: Can't compare a
collection to an object or collection; use contains() to test for
membership.
#v1.get("/get-specific-groups/{group_name}", tags=["GROUP"])
def get_specific_groups(group_name: str, current_user: CreateGroupSchema = Depends(get_current_user), db: Session = Depends(get_db)):
return db.query(User, Group, GroupColumnsData).join(GroupColumnsData).filter(Group.owner_username == current_user.get("username")).all()
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
username = Column(String(60), unique=True, nullable=False)
email = Column(String(80), unique=True, nullable=False)
password = Column(String(140), nullable=False)
groups = relationship("Group", backref="owner")
class Group(Base):
__tablename__ = "groups"
id = Column(Integer, primary_key=True, index=True)
group_name = Column(String(60), unique=True, nullable=False)
description = Column(String, nullable=False)
owner_username = Column(String, ForeignKey("users.username"), default=User.username)
group_username = relationship("GroupColumnsData", backref="group_owner")
class GroupColumnsData(Base):
__tablename__ = "groupsColumnsData"
id = Column(Integer, primary_key=True, index=True)
payee_name = Column(String(60))
item_name = Column(String(100))
amount_spent = Column(Integer)
owner_group = Column(String, ForeignKey("groups.group_name"), default=Group.group_name)
class GroupBorrowLendingData(Base):
__tablename__ = "groupsBorrowLendingData"
id = Column(Integer, primary_key=True, index=True)
lender = Column(String(60))
money_borrowed = Column(Integer)
borrower = Column(String(60))
owner_group = Column(String, ForeignKey("groups.group_name"), default=Group.group_name)
The Following code worked!
#v1.get("/get-specific-groups/{group_name}", tags=["GROUP"])
def get_specific_groups(group_name: str, current_user: CreateGroupSchema = Depends(get_current_user), db: Session = Depends(get_db)):
return db.query(Group).filter(Group.owner_username == current_user.get("username")).filter(Group.group_name.match(group_name)).all()

Save multiple media pictures for a value in database

I have a Table called property that accepts a contains column which refers to propertyContains table, then propertyContains will have a media column which refers to media table. i have no idea if i am storing the images the right way and i am wondering if there is any better/more efficient ways.
my code
class Property(Base):
__tablename__ = "property"
property_id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("propertyOwner.user_id"))
title = Column(String)
description = Column(String)
Location = Column(String)
rented = Column(Boolean)
rented_by = Column(Integer, ForeignKey("client.client_id"))
contains = relationship("PropertyContains", back_populates="contains_owner")
owner = relationship("Owner", back_populates="properties")
date = Column(Date, default=func.now())
class Config:
arbitrary_types_allowed = True
class Media(Base):
__tablename__ = "media"
media_id = Column(Integer, unique=True, primary_key=True, index=True)
media1 = Column(LargeBinary)
media2 = Column(LargeBinary)
media3 = Column(LargeBinary)
media_owner = Column(Integer, ForeignKey('propertyContains.property_contains_id', ondelete="CASCADE"))
class Config:
arbitrary_types_allowed = True
class PropertyContains(Base):
__tablename__ = "propertyContains"
property_contains_id = Column(Integer, unique=True, primary_key=True, index=True)
property_id = Column(Integer, ForeignKey("property.property_id"))
# media_id = Column(Integer, ForeignKey("media.media_id"))
bed_rooms = Column(Integer)
media = relationship("Media", backref="media", passive_deletes=True)
contains_owner = relationship("Property", back_populates="contains")
class Config:
arbitrary_types_allowed = True
please keep in note that i am a beginner <3.

fastAPI sqlalchemy - inner JOIN on 2 tables

I have a restapi up and running using the fastAPI framework, which is starting to work well.
Now: I already have my MySQL code on how to inner join on 2 tables, and I want to be able to do the same, just using sqlalchemy.
Firstly, here is my SQL code which works perfectly:
select `the_user`.`email_adress`, `the_exercise`.`exercise_name`, `run_the_workout`.`repetitions`,`run_the_workout`.`sets`,`run_the_workout`.`pause_time`,`run_the_workout`.`day_to_perform_the_task`
from `workout_plan_task` `run_the_workout`
inner join `user_profiles` `the_user` on `run_the_workout`.the_user=`the_user`.user_id
inner join `exercises` `the_exercise` on `the_exercise`.`exercise_ID` = `run_the_workout`.`the_exercise`
WHERE `run_the_workout`.the_user=1
Now, here are my table models in SQL alchemy, representing the "user_profiles", "exercises" and the "workout_plan_task" table:
#models.py:
class UserProfiles(Base):
__tablename__ = "user_profiles"
user_ID = Column(Integer, primary_key=True, index=True)
email_adress = Column(String, unique=True)
age = Column(Integer)
sex = Column(Integer)
height = Column(Integer)
weight = Column(Integer)
main_goal = Column(Integer)
level_experience = Column(Integer)
profile_created_at = Column(Date)
class Exercises(Base):
__tablename__ = "exercises"
exercise_ID = Column(Integer, primary_key=True, index=True)
exercise_name = Column(String)
exercise_type = Column(String, nullable=True)
muscle_groups_worked_out = Column(String)
equipment_ID = Column(Integer, nullable=True)
class WorkOutPlanTask(Base):
__tablename__ = "workout_plan_task"
task_ID = Column(Integer, primary_key=True, index=True)
user_ID = Column(Integer, ForeignKey("user_profiles.user_ID"))
workout_plan_ID = Column(Integer, ForeignKey("workout_plan.workout_plan_ID"))
exercise_ID = Column(Integer, ForeignKey("exercises.exercise_ID"))
repetitions = Column(Integer)
sets = Column(Integer)
pause_time = Column(Integer)
day_to_perform_the_task = Column(String)
inside my "crud.py" file, im trying to run the query using inner joins:
#crud.py
def get_workout_plan_for_user(db: Session, user_id:int):
return db.query(models.WorkOutPlanTask).join(models.UserProfiles, models.UserProfiles.user_ID == models.WorkOutPlanTask.user_ID).join(models.Exercises, models.Exercises.exercise_ID == models.WorkOutPlanTask.exercise_ID).filter(models.UserProfiles.user_ID == user_id)
and inside my #main.py i have this:
#app.get("/all_workout_plan_tasks_for_user/{user_id}")
def get_workout_plan_for_user_by_userID(user_id: int, db:Session = Depends(get_db)):
db_workout_plan = crud.get_workout_plan_for_user(db, user_id=user_id)
if db_workout_plan is None:
raise HTTPException(status_code=404, detail="sorry.. no workoutplans found ..")
return [schemas.a_workout_plan_task.from_orm(v) for v in db.query(...)]
This gives me the error:
sqlalchemy.exc.InvalidRequestError: SQL expression, column, or mapped entity expected - got 'Ellipsis'
Anyone here who could help me?
That's a funny mistake, take a look at the return statement:
return [schemas.a_workout_plan_task.from_orm(v) for v in db.query(...)]
You're passing Ellipsis to your db.query, and obviously, it's not the expected value.

how can I use a column that is not a Primary Key as a Foreign Key?

This might be a dumb question, but I can't find anything that indicates that you can't, however, when I try it, it does not work. I have an example of such an instance, but I can't reproduce the results.
Using SQLAlchemy, here is the working instance:
class Commissions(Base):
__tablename__ = "commissions"
id = Column(
Integer,
Sequence("commission_id", optional=True),
primary_key=True
)
commission_period_name = Column(
Unicode(40), ForeignKey("commission_periods.name"))
commission_period = relationship(
"CommissionPeriods",
primaryjoin="CommissionPeriods.name == Commissions.commission_period_name",
uselist=False,
backref="commissions"
)
agent_id = Column(Integer, ForeignKey("agents.id"))
agent = relationship(
Agents,
primaryjoin=Agents.id == agent_id,
uselist=False,
backref="commissions"
)
create_stamp = Column(DateTime)
commission_type = Column(Unicode(40))
amount = Column(Numeric(10, 2))
transactions_id = Column(Integer, ForeignKey(Transactions.id))
transaction = relationship(Transactions, primaryjoin=Transactions.id ==
transactions_id, backref="commissions", uselist=False)
Note the commission_period uses name, not an id as reference.
Here is the CommissionPeriods table definition:
class CommissionPeriods(Base):
__tablename__ = "commission_periods"
id = Column(
Integer,
Sequence("commission_periods_id", optional=True),
primary_key=True
)
name = Column(Unicode(40), index=True)
start_date = Column(DateTime(), index=True)
end_date = Column(DateTime(), index=True)
network = Column(Unicode(40), index=True)
status = Column(Unicode(40), index=True)
created_by = Column(Unicode(40))
create_stamp = Column(DateTime())
modify_stamp = Column(DateTime())
The alembic scripts runs without errors.
I have tried to replicate the results, with different tables (more or less the same table structures, with a name column that I am trying to use as a FK), but I have had no luck - on the python side everything is okay, but once I try to run the alembic scripts it tells me that the Foreign key is incorrectly formed.
Can someone please explain to me how this works, why it works in the given instance but not when I try to replicate the results from the above?
This is what I have tried in replicating the results:
class Networks(Base):
__tablename__ = "networks"
id = Column(
Integer,
Sequence('networks_id', optional=True),
primary_key=True
)
name = Column(Unicode(40), index=True)
rica_name = Column(Unicode(40))
net_iccid_start = Column(Integer)
net_iccid_end = Column(Integer)
net_iccid_int = Column(Integer)
network_class = Column(Unicode(60))
_config = Column("config", Unicode(2048))
Note that in the above table I want to use the name column as foreign key in:
class AgentRecharges(Base):
__tablename__ = "agent_recharges"
id = Column(
Integer,
Sequence('agent_recharges_id', optional=True),
primary_key=True
)
status = Column(Unicode(40))
create_stamp = Column(DateTime, index=True)
create_by = Column(Integer, ForeignKey(Agents.id))
create_by_agent = relationship(
Agents, primaryjoin=Agents.id == create_by, uselist=False)
modify_stamp = Column(DateTime, index=True)
complete_stamp = Column(DateTime, index=True)
msisdn = Column(Unicode(20), index=True, nullable=False)
amount = Column(Float, index=True, nullable=False)
network_name = Column(Unicode(40), ForeignKey(
"networks.name"), nullable=False)
network = relationship(
"Networks", primaryjoin="Networks.name == AgentRecharges.network_name", uselist=False)
iccid = Column(Unicode(40))
sim = relationship(Sims, backref="agent_recharges")
agents_id = Column(Integer, ForeignKey(Agents.id))
agent = relationship(Agents, primaryjoin=Agents.id ==
agents_id, uselist=False)
transactions_id = Column(Integer, ForeignKey(Transactions.id))
transaction = relationship(Transactions, primaryjoin=Transactions.id ==
transactions_id, backref="agent_recharges", uselist=False)
recharge_batch_id = Column(Integer, ForeignKey(RechargeBatches.id))
recharge_batch = relationship(RechargeBatches)
When I run the alembic script to add this new table, it tells me that the foreign key is incorrectly formed.
Any ideas on why, and how I can accomplish my goal?

Better way to filter join against a list of values in SQLAlchemy?

In my schema, a Hardware item may have zero or more Mods recorded against it. I'm trying to filter a query based on an exact match against a list of mods. For example, I might want to filter for Hardware which has mods [2,3,5], and no others.
At the moment, I'm grouping and counting to check that the number of mods is correct, then adding a filter in a for loop to match the exact mod numbers:
...
query = query.join(Hardware).join(Mod)
query = query.group_by(Tag.tag_id).having(len(v['m']) == func.count(Mod.mod_number))
for m in v['m']:
query = query.filter(Hardware.mods.any(mod_number=m))
...
Is there a better way to express this using SQLAlchemy? In particular, the documentation recommends against using func.count() because it fails in some corner cases..
My schema looks like this:
Base = declarative_base()
class Tag(Base):
__tablename__ = 'tag'
tag_id = Column(Integer, primary_key=True)
order_code = Column(String, nullable=False)
version = Column(String, nullable=False)
status = Column(String, nullable=False)
comments = Column(String)
software = relationship(
"Software",
backref="tag",
collection_class=attribute_mapped_collection('artefact'),
)
hardware = relationship(
"Hardware",
backref="tag",
collection_class=attribute_mapped_collection('artefact'),
)
__table_args__ = (
UniqueConstraint('order_code', 'version'),
)
def as_dict(self):
d = as_dict_columns(self)
d['software'] = {s: as_dict_columns(self.software[s]) for s in self.software}
d['hardware'] = {h: self.hardware[h].as_dict() for h in self.hardware}
return d
class Software(Base):
__tablename__ = 'software'
software_id = Column(Integer, primary_key=True)
tag_id = Column(String, ForeignKey('tag.tag_id'))
artefact = Column(String, nullable=False)
version = Column(String, nullable=False)
__table_args__ = (
UniqueConstraint('tag_id', 'artefact'),
)
def __str__(self):
""" This is to deal with Jinja2/SQLAlchemy wackiness """
return self.version
class Hardware(Base):
__tablename__ = 'hardware'
hardware_id = Column(Integer, primary_key=True)
tag_id = Column(String, ForeignKey('tag.tag_id'))
product_id = Column(String, nullable=True)
artefact = Column(String, nullable=False)
version = Column(String, nullable=False)
mods = relationship("Mod", backref="hardware")
__table_args__ = (
UniqueConstraint('tag_id', 'product_id'),
)
def as_dict(self):
d = as_dict_columns(self)
d['mods'] = self.__list_mods__()
return d
class Mod(Base):
__tablename__ = 'mod'
hardware_id = Column(String, ForeignKey('hardware.hardware_id'), primary_key=True)
mod_number = Column('mod_number', Integer, primary_key=True, nullable=False)
__table_args__ = (
UniqueConstraint('hardware_id', 'mod_number'),
)

Categories

Resources