SQLAlchemy query tables joined with foreign key

mic*_*3pl 3 python sqlalchemy

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)

Ilj*_*ilä 5

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的枚举类:

使用枚举类时,枚举对象同时用于输入和输出,而不是像普通字符串枚举类型那样使用字符串...