SQLAlchemy查询表与外键连接

时间:2018-01-09 18:31:26

标签: python sqlalchemy

我试图通过Flask-SQLAlchemy查询从MySQL显示数据,并将外键(category_id)更改为name_id的名称。更确切地说 - enter image description here

使用查询我想显示名称来自类别Table的项目,而不是category_id。

这是我的代码:

class MyEnum(enum.Enum):
    piece = "piece"
    kg = "kg"

class Category(db.Model):
    __tablename__ = 'category'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(25), nullable=False)

class Product(db.Model):
    __tablename__ = 'product'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30), nullable=False)
    quantity = db.Column(db.Integer, nullable=False)
    product_type = db.Column(db.Enum(MyEnum), nullable=False)
    category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
    description = db.Column(db.String(255))

    category = db.relationship("Categ{{user.id}}ory",
                            backref=('products'))


    def __init__(self,name, quantity, product_type, category_id, description):
        self.name = name
        self.quantity = quantity
        self.product_type = product_type
        self.category_id = category_id
        self.description = description


db.create_all()
db.session.commit()

@app.route('/grocery-list', methods=['GET'])
def display_data():
    data = Product.query.all()
    category_name = db.session.query(Product).join(Category, Product.category_id == Category.name)
    return render_template('query_database.html', data=data, category_name = category_name)

#query_database.html
<body>
    {% for user in data %}
        <li>{{user.id}}.   {{user.name}}  {{user.quantity}}  {{user.product_type}} Category {{user.category_id}}  {{user.description}}</li>
    {% endfor %}
    {{ category_name }}
</body>

query_Database.html:

的结果
3. Ziemniaczki 2 MyEnum.kg Category 1 Na obiad

SELECT product.id AS product_id, product.name AS 
product_name,product.quantity AS product_quantity, product.product_type AS product_product_type, product.category_id AS product_category_id, 
product.description AS product_description FROM product INNER JOIN category ON product.category_id = category.name 

问题:

1)如何创建此类查询?我概述了在纯SQL中它应该是什么样子但我在SqlAlchemy的文档中找不到相同的东西:

select p.name, c.name
from product as p
join category as c
on c.id = p.category_id 

2)MyEnum.kg在那里做什么?如何从这个视图中删除My.Enum?

编辑 - 成功

如果有人需要,只需离开工作代码。

@app.route('/grocery-list', methods=['GET'])
def display_data():
    data = db.session.query(Product, Category).join(Category).all()
    return render_template('query_database.html', data=data)

    {% for user, category in data  %}
    <li>{{user.id}}. {{user.name}}  {{user.quantity}}  {{user.product_type}} Category {{user.category.name}}  {{user.description}}</li>
    {% endfor %}

解决方案

连接表后,在模板文件中需要使用

解包category.name的值
{{user.category.name}}  

1 个答案:

答案 0 :(得分:1)

  

1)如何创建此类查询?我概述了在纯SQL中它应该是什么样子但我在SqlAlchemy的文档中找不到相同的东西

以下是一些您可能会觉得有用的链接:

由于您已经定义了ProductCategory之间的ORM关系,因此您可以eager load相关类别以及产品:

data = Product.query.options(db.joinedload(Product.category)).all()

然后您可以在模板中访问user.category.name,而不会发出新的查询。另一个更像SQL的解决方案是获取Product, Category元组,这看起来就像你所追求的那样:

# No need to explicitly define the ON clause of the join, unless you
# really want to. SQLAlchemy examines the foreign key(s) and does what
# needs to be done.
data = db.session.query(Product, Category).join(Category).all()

然后在您的模板中解压结果元组:

<!-- I don't understand why it's called "user" -->
{% for user, category in data %}
    ...
{% endfor %}
  

2)MyEnum.kg在那里做什么?如何从这个视图中删除My.Enum?

这只是枚举的字符串表示形式:

In [4]: str(MyEnum.kg)
Out[4]: 'MyEnum.kg'

如果您对此不满意,您会想要修改{{user.product_type}}以满足您的需求。您已为该列使用了SQLAlchemy Enum类型和符合PEP-435的枚举类:

  

当使用枚举类时,枚举对象既用于输入又用于输出,而不是字符串,就像普通字符串枚举类型一样......