I am trying to display data from MySQL via Flask-SQLAlchemy query and change foreign key (category_id) into name assign to the category_id. To be more precise - 
With the query I want to display item with the name from category Table, not the category_id.
Here is my code:
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>
Run Code Online (Sandbox Code Playgroud)
Result of 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
Run Code Online (Sandbox Code Playgroud)
Questions:
1) How to create such query? I got overview how should this look like in pure SQL but I can't find equivalent in documentation of SqlAlchemy :
select p.name, c.name
from product as p
join category as c
on c.id = p.category_id
Run Code Online (Sandbox Code Playgroud)
2) What MyEnum.kg is doing out there? How to delete the My.Enum from the this view?
EDIT - Success
Just leaving the working code, if someone would ever need so.
@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 %}
Run Code Online (Sandbox Code Playgroud)
Solution
After joining tables, in template file it's required to unpack the value of the category.name with
{{user.category.name}}
Run Code Online (Sandbox Code Playgroud)
1)如何创建这样的查询?我概述了这在纯 SQL 中应该是什么样子,但我在 SqlAlchemy 的文档中找不到等价物
以下是一些您可能会觉得有用的链接:
由于您已经定义了Product和之间的 ORM 关系Category,您可以预先加载相关类别以及产品:
data = Product.query.options(db.joinedload(Product.category)).all()
Run Code Online (Sandbox Code Playgroud)
然后你可以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()
Run Code Online (Sandbox Code Playgroud)
然后在你的模板中解压结果元组:
<!-- I don't understand why it's called "user" -->
{% for user, category in data %}
...
{% endfor %}
Run Code Online (Sandbox Code Playgroud)
2) MyEnum.kg 在那里做什么?如何从此视图中删除 My.Enum?
这只是枚举的字符串表示:
In [4]: str(MyEnum.kg)
Out[4]: 'MyEnum.kg'
Run Code Online (Sandbox Code Playgroud)
{{user.product_type}}如果您对它不满意,您将需要进行修改以满足您的需求。您已经为该列使用了 SQLAlchemyEnum类型和符合PEP-435的枚举类:
使用枚举类时,枚举对象同时用于输入和输出,而不是像普通字符串枚举类型那样使用字符串...
| 归档时间: |
|
| 查看次数: |
8896 次 |
| 最近记录: |