I'm about to create query select join
with sqlalchemy
like:
SELECT position.*, device.name as devicename
FROM `position` JOIN `device`
ON position.id_device = device.id
ORDER BY position.id_device
So in python file, I create the query like the following:
result = sql.query(Position, Device).\
join(Device, Position.id_device == Device.id).\
order_by(Position.id_device).first()
I got the result:
[
{
"id": 1,
"size": "600x300",
"price": 150,
"id_category": 0,
"id_device": 1,
"impression": 9999,
"status": 1,
"name": "Home Top Banner",
"id_website": 1
},
{
"deleted_at": null,
"status": 1,
"name": "Desktop",
"id": 1
}
]
The result that i want as the mysql
query above is:
[
{
"id": 1,
"size": "600x300",
"price": 150,
"id_category": 0,
"id_device": 1,
"impression": 9999,
"status": 1,
"name": "Home Top Banner",
"id_website": 1,
"devicename": "Desktop",
}
]
The main code flow:
[...]
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
[...]
from sqlalchemy.orm import Session
def db_session() -> Generator:
"""
Get database connection with DI (Dependencies Injection)
"""
try:
dbsession = SessionLocal()
yield dbsession
finally:
dbsession.close()
@router.get('/{ad_type}')
def ad_unit(
ad_type: str,
sql: Session = Depends(db_session)
):
"""Display ads unit of the available product"""
result = get_position(sql, ad_type=ad_type)
return result
[...]
def get_position(sql: Session, ad_type: str):
result = sql.query(Position, Device).\
join(Device, Position.id_device == Device.id).\
order_by(Position.id_device).first()
[...]
Model classes:
from sqlalchemy import Column
from sqlalchemy.dialects import mysql
from app.settings.mysql_settings import Base
class Position(Base):
"""A class used to represent position table (ads price list & dimensions)"""
__tablename__ = 'position'
id = Column(mysql.INTEGER(display_width=11, unsigned=True), primary_key=True,
index=True, autoincrement=True)
id_device = Column(mysql.INTEGER(display_width=11), nullable=True)
id_website = Column(mysql.INTEGER(display_width=11), nullable=True)
id_category = Column(mysql.INTEGER(display_width=11), nullable=True)
name = Column(mysql.VARCHAR(length=50, collation="utf8_unicode_ci"), nullable=True)
price = Column(mysql.INTEGER(display_width=11), nullable=True)
status = Column(mysql.TINYINT(display_width=1), nullable=True, default=1)
size = Column(mysql.TEXT(collation="utf8_unicode_ci"), nullable=True)
impression = Column(mysql.DOUBLE(), nullable=False, default=0)
class Device(Base):
"""A class used to represent a list of device type for ads unit e.g: Mobile, Desktop, etc."""
__tablename__ = 'device'
id = Column(mysql.INTEGER(display_width=11), primary_key=True,
index=True, autoincrement=True)
name = Column(mysql.VARCHAR(length=50, collation="latin1_swedish_ci"), nullable=True)
status = Column(mysql.TINYINT(display_width=1), nullable=True, default=1)
deleted_at = Column(mysql.TIMESTAMP(), nullable=True)
I've tried many ways to get the result that I want, by merge/union the result and others but it doesn't work. I think there's a specific way to get the result that I want with sqlalchemy
but I cannot found it in the doc because there are so many references.
Any help would be appreciated, thanks.
To translate a query like this:
SELECT users.name AS users_name,
addresses_1.email_address AS addresses_1_email_address,
addresses_2.email_address AS addresses_2_email_address
FROM users JOIN addresses AS addresses_1
ON users.id = addresses_1.user_id
JOIN addresses AS addresses_2
ON users.id = addresses_2.user_id
WHERE addresses_1.email_address = ?
AND addresses_2.email_address = ?
('jack@google.com', 'j25@yahoo.com')
the equivalent SQL alchemy syntax is this:
>>> from sqlalchemy.orm import aliased
>>> adalias1 = aliased(Address)
>>> adalias2 = aliased(Address)
SQL>>> for username, email1, email2 in \
... session.query(User.name, adalias1.email_address, adalias2.email_address).\
... join(User.addresses.of_type(adalias1)).\
... join(User.addresses.of_type(adalias2)).\
... filter(adalias1.email_address=='jack@google.com').\
... filter(adalias2.email_address=='j25@yahoo.com'):
... print(username, email1, email2)
Well, I finally found the answer, I've tried so many ways and you know what print
save my day:D
So, I found 2 solutions here, and both of it is work like want I want. The first one is still using the ORM style, and the second one by doing the raw
query
j = join(Position, Device, Position.id_device == Device.id)
stmt = select([Position, Device.name.label('devicename')]).select_from(j)
result = sql.execute(stmt)
return result.fetchall()
# or by raw query
result = sql.execute("""SELECT position.*, device.name as devicename
FROM `position`
JOIN `device` on position.id_device = device.id
ORDER BY position.id_device""")
return result.fetchall()
That's it. Thank you all for your help.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.