gpt4 book ai didi

python - 具有多个连接的 SQLAlchemy 查询

转载 作者:行者123 更新时间:2023-11-28 22:26:16 25 4
gpt4 key购买 nike

我正在使用 SQLAlchemy 和 Postgres 创建一个 flask 应用程序。我对此很陌生,所以我将不胜感激任何反馈。但是,我的直接问题是在以下模型上构建查询。

from app import db
from sqlalchemy import or_, and_


# Items Table
class Item(db.Model):

__tablename__ = "items"

id = db.Column(db.Integer, primary_key=True)
itemName = db.Column(db.String, unique=True, nullable=False)
measurement = db.Column(db.String, nullable=False)
defaultPrice = db.Column(db.Float, nullable=False)
minimumOrder = db.Column(db.Float, nullable=False)
maximumOrder = db.Column(db.Float, nullable=False)
orders = db.relationship('Order', back_populates='item')
prices = db.relationship('Price', back_populates='item')

def __init__(self, itemName, measurement, defaultPrice,
minimumOrder, maximumOrder):
self.itemName = itemName
self.measurement = measurement
self.defaultPrice = defaultPrice
self.minimumOrder = minimumOrder
self.maximumOrder = maximumOrder

def __repr__(self):
return '<Item {0}>'.format(self.id)


# Users Table
class User(db.Model):

__tablename__ = 'users'

id = db.Column(db.Integer, primary_key=True)
fullName = db.Column(db.String, unique=True, nullable=False)
userName = db.Column(db.String, unique=True, nullable=False)
password = db.Column(db.String, nullable=False)
role = db.Column(db.String, nullable=False)
orders = db.relationship('Order', back_populates='user')
prices = db.relationship('Price', back_populates='user')

def __init__(self, fullName, userName, password, role):
self.fullName = fullName
self.userName = userName
self.password = password
self.role = role

def __repr__(self):
return '<User {0}>'.format(self.userName)


# Availability / Price Table
class Price(db.Model):

__tablename__ = 'prices'

id = db.Column(db.Integer, primary_key=True)
userId = db.Column(db.Integer, db.ForeignKey('users.id'))
user = db.relationship('User', back_populates='prices')
itemId = db.Column(db.Integer, db.ForeignKey('items.id'))
item = db.relationship('Item', back_populates='prices')
available = db.Column(db.Boolean)
priceMeasurement = db.Column(db.String)
price = db.Column(db.Float)

def __init__(self, userId, itemId, priceMeasurement, price):
self.userId = userId
self.itemId = itemId
self.priceMeasurement = priceMeasurement
self.price = price

def __repr__(self):
return '<Price {0}>'.format(self.price)


# Orders Table
class Order(db.Model):

__tablename__ = 'orders'

id = db.Column(db.Integer, primary_key=True)
userId = db.Column(db.Integer, db.ForeignKey('users.id'))
user = db.relationship('User', back_populates='orders')
itemId = db.Column(db.Integer, db.ForeignKey('items.id'))
item = db.relationship('Item', back_populates='orders')
orderQuantity = db.Column(db.Float)
orderMeasurement = db.Column(db.String)
orderPrice = db.Column(db.Float)
orderDelivery = db.Column(db.Date)
orderPlaced = db.Column(db.Date)

def __init__(self, userId, itemId, orderQuantity,
orderMeasurement, orderPrice, orderDelivery, orderPlaced):
self.userId = userId
self.itemId = itemId
self.orderQuantity = orderQuantity
self.orderMeasurement = orderMeasurement
self.orderPrice = orderPrice
self.orderDelivery = orderDelivery
self.orderPlaced = orderPlaced

def __repr__(self):
return '<Order {0}>'.format(self.orderDelivery)

我希望从查询中返回一个类似于以下查询返回的表:

SELECT * FROM items
JOIN prices ON prices.itemId=items.id
WHERE prices.userId = 1 AND prices.available = True
LEFT JOIN (
SELECT * FROM orders WHERE orderDelivery = '2017-07-05') as orders
ON orders.itemId=items.id

在 SQLAlchemy 查询中。我会将 userId 和 orderDelivery 变量传递给路由和 session 中的查询 - @app.route('/user/order/<order_date>') | session['userID'] : 在登录时建立。

谢谢

最佳答案

如果我没理解错的话,您想要查询 (Item, Price, Order) 实体的元组,其中 Order 来自子查询。这在 Selecting Entities from Subqueries 下的对象关系教程中进行了解释.

In [5]: from datetime import date

In [6]: orders_sq = db.session.query(Order).\
...: filter(Order.orderDelivery == date(2017, 7, 5)).\
...: subquery()

In [7]: orders_alias = db.aliased(Order, orders_sq)

In [8]: query = db.session.query(Item, Price, orders_alias).\
...: join(Price).\
...: outerjoin(orders_alias, Item.orders).\
...: filter(Price.userId == 1,
...: Price.available)

以及针对 SQLite 编译时生成的 SQL:

In [9]: print(query)
SELECT items.id AS items_id, items."itemName" AS "items_itemName", items.measurement AS items_measurement, items."defaultPrice" AS "items_defaultPrice", items."minimumOrder" AS "items_minimumOrder", items."maximumOrder" AS "items_maximumOrder", prices.id AS prices_id, prices."userId" AS "prices_userId", prices."itemId" AS "prices_itemId", prices.available AS prices_available, prices."priceMeasurement" AS "prices_priceMeasurement", prices.price AS prices_price, anon_1.id AS anon_1_id, anon_1."userId" AS "anon_1_userId", anon_1."itemId" AS "anon_1_itemId", anon_1."orderQuantity" AS "anon_1_orderQuantity", anon_1."orderMeasurement" AS "anon_1_orderMeasurement", anon_1."orderPrice" AS "anon_1_orderPrice", anon_1."orderDelivery" AS "anon_1_orderDelivery", anon_1."orderPlaced" AS "anon_1_orderPlaced"
FROM items JOIN prices ON items.id = prices."itemId" LEFT OUTER JOIN (SELECT orders.id AS id, orders."userId" AS "userId", orders."itemId" AS "itemId", orders."orderQuantity" AS "orderQuantity", orders."orderMeasurement" AS "orderMeasurement", orders."orderPrice" AS "orderPrice", orders."orderDelivery" AS "orderDelivery", orders."orderPlaced" AS "orderPlaced"
FROM orders
WHERE orders."orderDelivery" = ?) AS anon_1 ON items.id = anon_1."itemId"
WHERE prices."userId" = ? AND prices.available = 1

另外,您也可以简单地将声明传递给 Query.from_statement有一些修复和更改:

In [45]: query2 = db.session.query(Item, Price, Order).\
...: from_statement(db.text("""
...: SELECT * FROM items
...: JOIN prices ON prices.itemId=items.id
...: LEFT JOIN (
...: SELECT * FROM orders WHERE orderDelivery = :orderDelivery) as orders
...: ON orders.itemId=items.id
...: WHERE prices.userId = :userId AND prices.available
...: """)).\
...: params(userId=1, orderDelivery='2017-07-05')

但我建议使用前一种方法,因为它与数据库无关。

关于python - 具有多个连接的 SQLAlchemy 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44948865/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com