sqlalchemy - 在 sqlalchemy ORM 中加载外连接结果
问题描述
我需要在这个结构中加载结果:
{
addresses: [,…]
birth_date: "YYYY-MM-DD"
created_at: "2020-09-29T15:27:30.789498"
disabled: false
email: "sami@email.me"
email_confirmed: false
gender: "m"
id: 11
items: [,…]
mobile: 80080080
mobile_confirmed: true
name_first: "Sami"
name_last: "xx"
newsletter: true
orders: [,…]
preferred_language: "ar"
updated_at: "2020-11-13T15:21:57.301272"
}
但我越来越空orders
了items
。他们的列没有加载。
class Users(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
name_first = Column(String, nullable=False)
name_last = Column(String, nullable=True)
mobile = Column(Integer, unique=True, index=True, nullable=False)
mobile_otp= Column(Integer, nullable=False)
mobile_confirmed = Column(Boolean, default=False)
email = Column(String, unique=True, index=True, nullable=True)
email_confirmed = Column(Boolean, default=False)
password = Column(String, nullable=False)
password_reset_otp = Column(Integer, nullable=True)
gender= Column(String, nullable=False)
birth_date= Column(DateTime, nullable=False)
preferred_language = Column(String, nullable=False)
newsletter = Column(Boolean, default=False)
disabled = Column(Boolean, default=False)
created_at= Column(DateTime, nullable=False)
updated_at= Column(DateTime, nullable=False)
addresses = relationship('Addresses', uselist=True, back_populates="user", lazy='noload')
orders = relationship('Orders', uselist=True, backref=backref("user"), lazy='noload')
items = relationship('Items', uselist=True, backref=backref("user"), lazy='noload')
staff = relationship("Staff", uselist=False, back_populates="user", lazy='raise')
class Orders(Base):
__tablename__="orders"
id= Column(Integer, primary_key=True, index=True)
user_id= Column(Integer, ForeignKey('users.id'))
address_id= Column(Integer, ForeignKey('addresses.id'))
delivery_at= Column(DateTime)
staff_id= Column(Integer, ForeignKey('staff.id'), nullable=True)
store_id= Column(Integer, ForeignKey('stores.id'), nullable=True)
created_at= Column(DateTime)
updated_at= Column(DateTime)
active = Column(Boolean, default=True)
items = relationship("Items", uselist=True, back_populates="order", lazy='raise')
lifecycle = relationship("OrderLifeCycles")
class Items(Base):
__tablename__="items"
id= Column(Integer, primary_key=True, index=True)
user_id= Column(Integer, ForeignKey('users.id'))
order_id = Column(Integer, ForeignKey('orders.id'), nullable=True)
size_id = Column(Integer, ForeignKey('sizes.id'))
price = Column(Float, nullable=True)
qty = Column(Integer)
order= relationship("Orders", uselist=False, back_populates="items", lazy='raise')
size= relationship("Sizes", uselist=False, lazy='raise')
SQLAlchemy 查询:
def get_user_by_mobile(db: Session, mobile: str, items: bool, orders:bool):
orders = db.query(tables.Orders).filter(tables.Orders.active==True).subquery("orders")
items = db.query(tables.Items).options(joinedload(tables.Items.size).joinedload(tables.Sizes.product)).filter(tables.Items.order_id==None).subquery("items")
query = db.query(tables.Users).outerjoin(items, tables.Users.id == items.c.user_id).outerjoin(orders, tables.Users.id == orders.c.user_id)
query = query.options(joinedload(tables.Users.addresses)).filter(tables.Users.mobile == mobile)
return query.first()
如何在顶部的 json 结构示例中将子查询结果列表作为属性加载?类似于加载地址的方式。
查询语句中不包含子查询的列名:
SELECT users.id AS users_id,
users.name_first AS users_name_first,
users.name_last AS users_name_last,
users.mobile AS users_mobile,
users.mobile_otp AS users_mobile_otp,
users.mobile_confirmed AS users_mobile_confirmed,
users.email AS users_email,
users.email_confirmed AS users_email_confirmed,
users.password AS users_password,
users.password_reset_otp AS users_password_reset_otp,
users.gender AS users_gender,
users.birth_date AS users_birth_date,
users.preferred_language AS users_preferred_language,
users.newsletter AS users_newsletter,
users.disabled AS users_disabled,
users.created_at AS users_created_at,
users.updated_at AS users_updated_at,
addresses_1.id AS addresses_1_id,
addresses_1.label AS addresses_1_label,
St_asewkb(addresses_1.coordinates) AS addresses_1_coordinates,
addresses_1.building_number AS addresses_1_building_number,
addresses_1.flat_number AS addresses_1_flat_number,
addresses_1.disabled AS addresses_1_disabled,
addresses_1.created_at AS addresses_1_created_at,
addresses_1.updated_at AS addresses_1_updated_at,
addresses_1.user_id AS addresses_1_user_id
FROM users
left outer join
(
SELECT items.id AS id,
items.user_id AS user_id,
items.order_id AS order_id,
items.size_id AS size_id,
items.price AS price,
items.qty AS qty
FROM items
WHERE items.order_id IS NULL) AS anon_1
ON users.id = anon_1.user_id
left outer join
(
SELECT orders.id AS id,
orders.user_id AS user_id,
orders.address_id AS address_id,
orders.delivery_at AS delivery_at,
orders.staff_id AS staff_id,
orders.store_id AS store_id,
orders.created_at AS created_at,
orders.updated_at AS updated_at,
orders.active AS active
FROM orders
WHERE orders.active = TRUE) AS anon_2
ON users.id = anon_2.user_id
left outer join addresses AS addresses_1
ON users.id = addresses_1.user_id
WHERE users.mobile = %(mobile_1)s
解决方案
推荐阅读
- php - 使用 Codeigniter3 加载完整的日历事件
- c++ - 如何从 UI 将 QMediaPlayer 归因于 QWidget?获得填充QWidget字段的效果
- javascript - WebAudio 调度非 AudioParam 事件
- jenkins - 在执行工作时它在詹金斯中失败了
- multithreading - 如何在 Rust 中同时运行不同的线程?
- javascript - 如果项目宽度不同,则 Slick Slider 项目的更改速度不同
- vb.net - 如何按 MS Access 的特定月份汇总特定列数据并进入 vb.net 中的文本框
- summernote - Summer Note Text Editor Don't Show Font Size in Blog Section in Journal Theme Open Cart 3
- c# - 收到消息时未检索到 msmq AppSpecific
- javascript - 在我的起始日期选择框中,我想显示当前会话日期范围之间的日期范围