Python中如何使用sqlalchemy进行join操作?
想要按用户取出产品的价格
原 SQL 工作语句
select pro.id as id,
pro.name as name,
pri.year1 as year1
from prices pri right outer join products pro on pri.product_id = pro.id where user_group_id=(select user_group_id from user_relationships where user_id=2);
搞了一晚上了,还是没能成功转成 sqlalchemy 查询方法。
products = Product.query.outerjoin(Price).filter_by(user_group_id=2)
sqlalchemy 构建的句子是这样,没有返回价格信息,
SELECT products.id AS products_id, products.name AS products_name, products.time_created AS products_time_created, products.time_updated AS products_time_updated
FROM products LEFT OUTER JOIN prices ON products.id = prices.product_id
WHERE prices.user_group_id = %s
Python中如何使用sqlalchemy进行join操作?
在SQLAlchemy里做JOIN操作,核心就是用query()配合join()方法。假设你有User和Order两个表,通过user_id关联,下面是一个完整的例子:
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
orders = relationship("Order", back_populates="user")
class Order(Base):
__tablename__ = 'orders'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('users.id'))
product = Column(String)
user = relationship("User", back_populates="orders")
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
# 插入测试数据
user1 = User(name="Alice")
session.add(user1)
session.add(Order(user=user1, product="Book"))
session.commit()
# INNER JOIN: 查询所有订单及对应的用户名
results = session.query(Order, User.name).join(User, Order.user_id == User.id).all()
for order, user_name in results:
print(f"Order ID: {order.id}, Product: {order.product}, User: {user_name}")
# 如果你定义了relationship,可以直接通过它来join,更简洁
results2 = session.query(Order).join(Order.user).all()
for order in results2:
print(f"Order ID: {order.id}, User: {order.user.name}")
# LEFT OUTER JOIN 使用 outerjoin()
results3 = session.query(User.name, Order.product).outerjoin(Order, User.id == Order.user_id).all()
for user_name, product in results3:
print(f"User: {user_name}, Product: {product or 'No orders'}")
关键点:
- 基本JOIN:
session.query(...).join(目标表, 关联条件) - 使用relationship:如果模型里定义了
relationship,可以直接join(模型类.relationship属性),SQLAlchemy会自动推导关联条件。 - LEFT JOIN:把
join()换成outerjoin()就行。 - 选择字段:在
query()里指定你要的字段或模型,比如query(Order, User.name)。
总结:用join()方法,配合模型关系让代码更简洁。
1.你的写法无法查出 Price 是因为你 query 的对象仅仅是 Product,尽管你做了显式 join,但是 SQLAlchemy 只会返回 Product 的信心。
2. 正确的写法有很多种,具体要看你的 Product, Price, User 三个 model 类是怎样建立 SQLAlchemy relationships 的。
其中一种最简单的写法,不管你三个类是什么关系都能用的写法,是隐式 jcross join: session.query(Product, Price).filter(Product.id == Price.id & Price.user_group_id == 2)
今天又搞了几小时弄好了
用 model 开始的查询 只返回 model 表的数据。 改用 db.session.query 并设置了别名

