【问题标题】:How to display a SQL INNER JOIN HTML with Flask如何使用 Flask 显示 SQL INNER JOIN HTML
【发布时间】:2019-10-18 09:12:39
【问题描述】:

我在显示另一个表中的值时遇到了一些问题(使用下面的代码会更容易理解):

contact.py

def index():
    db = get_db()
    contacts = db.execute(
        'SELECT *'
        ' FROM contact INNER JOIN branche ON contact.branche_id = branche.branche_id'
        ' ORDER BY contact.nom ASC'
    ).fetchall()
    return render_template('contact/index.html', contacts=contacts)

templates/contact/index.html

<table class="table table-hover">
      <thead class="thead-light">
          <th>Nom</th>
          <th>Prénom</th>
          <th>Adresse Mail</th>
          <th>Code Postal</th>
          <th>Ville</th>
          <th>Téléphone Portable</th>
          <th>Branche</th>
      </thead>
      <tbody>
      <div class="col-md-4">
        <div class="form-group">
      <div runat="server" id="div_columns" >
        {% for contact in contacts %}
         <tr>
             <td>{{ contact['nom'] }}</td>
             <td>{{ contact['prenom'] }}</td>
             <td>{{ contact['telportable'] }}</td>
             <td>{{ contact['adressemail'] }}</td>
             <td>{{ contact['codepostal'] }}</td>
             <td>{{ contact['ville'] }}</td>
             <td>{{ contact['telportable'] }}</td>
             <td>{{ branche['branche_nom'] }}</td>
             <td> 
                <a class="btn"><i class="fas fa-pencil-alt"></i></a>
                <a class="btn text-danger "><i class="fa fa-trash fa-lg"></i></a>
            </td>
          </tr>
          {% endfor %}
              <hr>
          </div>
          </div>
          </div>
      </tbody>
    </table>

schema.sql

DROP TABLE IF EXISTS contact;
DROP TABLE IF EXISTS branche;

CREATE TABLE contact (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  nom TEXT NOT NULL,
  prenom TEXT NOT NULL,
  adressemail TEXT NOT NULL,
  adressepostale TEXT NOT NULL,
  codepostal INTEGER NOT NULL,
  ville TEXT NOT NULL,
  telfixe INTEGER NOT NULL,
  telportable INTEGER NOT NULL,
  branche_id INTEGER NOT NULL,
  FOREIGN KEY (branche_id) REFERENCES branche (branche_id)
);

CREATE TABLE branche (
  branche_id INTEGER PRIMARY KEY AUTOINCREMENT,
  branche_nom TEXT UNIQUE NOT NULL
);

我要做的就是打印联系人信息(姓名、电话号码……),contact 表中没有一个信息,它是branche_nom 里面branche 表,那么我的错误在哪里?我在终端计算机或浏览器终端内没有任何错误

P.S : 当我禁用 branche_nom 的显示时,存储在 DB 中的所有行都会被打印出来,我只是没有想要使用另一个表的东西

编辑 1:加载 branche

contact.py

def index():
    db = get_db()
    contacts = db.execute(
        'SELECT contact.nom, contact.prenom, contact.adressemail, contact.codepostal, contact.ville, contact.telportable, branche.branche_nom'
        ' FROM contact INNER JOIN branche ON contact.branche_id = branche.branche_id'
        ' ORDER BY contact.nom ASC'
    ).fetchall()
    branches = db.execute(
        'SELECT branche_nom'
        ' FROM branche INNER JOIN contact ON contact.branche_id = branche.branche_id'
    ).fetchall()
    return render_template('blog/index.html', contacts=contacts, branches=branches)

Branche List 的截图:

EDIT2:db.py

import sqlite3  
import click
from flask import current_app, g
from flask.cli import with_appcontext

def init_app(app):
    app.teardown_appcontext(close_db)
    app.cli.add_command(init_db_command)

def init_db():
    db = get_db()

    with current_app.open_resource('schema.sql') as d:
        db.executescript(d.read().decode('utf8'))

@click.command('init-db')
@with_appcontext
def init_db_command():
    """Clear the existing data and create new tables."""
    init_db()
    click.echo('Initialized the database.')


def get_db():
    if 'db' not in g:
        g.db = sqlite3.connect(
            current_app.config['DATABASE'],
            detect_types=sqlite3.PARSE_DECLTYPES
        )
        g.db.row_factory = sqlite3.Row

    return g.db

def close_db(e=None):
    db = g.pop('db', None)

    if db is not None:
        db.close()  

【问题讨论】:

  • 您根本没有将branche 变量传递给您的模板,也没有在查询中选择任何branche 列。
  • @AKX 我尝试添加它,但没有任何变化(目前)

标签: python html sql flask


【解决方案1】:

首先,检查分支表是否填充相关ID,因为当两个表上的ID都不存在时,内连接将返回空光标。

其次,我会尽量避免在选择中使用 * 并选择“SELECT contact.,branche.”或选择表格的实际列。

第三,在尝试使用sqlite编写代码后,我发现您应该在html模板中更改您当前的迭代器联系人而不是分支,

例如:不是&lt;td&gt;{{ branche['branche_nom'] }}&lt;/td&gt; 但是&lt;td&gt;{{ contact['branche_nom'] }}&lt;/td&gt;

除了错字之外,您必须在连接初始化后立即添加一个命令,该命令将通过名称识别您的列:db.row_factory = sqlite3.Row

我已经运行了你的完整示例并且它有效! 完整代码:

%%writefile contact.py
from flask import Flask, escape, url_for
from flask import render_template
import sqlite3

app = Flask(__name__)

def get_db():
    db = sqlite3.connect(r"/home/david/sqlite/db/pythonsqlite.db")
    return db

@app.route('/')
def index():
    db = get_db()
    db.row_factory = sqlite3.Row
    contacts = db.execute(
        'SELECT contact.nom, contact.prenom, contact.adressemail, contact.codepostal, contact.ville, contact.telportable, branche.branche_nom'
        ' FROM contact INNER JOIN branche ON contact.branche_id = branche.branche_id'
        ' ORDER BY contact.nom ASC'
    ).fetchall()
    return render_template('index.html', contacts=contacts)

结果:

造成混淆的主要原因是 Jinja 如何解释游标及其变量(列),不同的数据库有不同的 DB-API,幸运的是,您的第一种方法“理解”了名称列(但不是全部来自分支表),就好像您尝试遍历联系人一样,您将只能访问索引列(按数字),使用 sqlite3.Row 的附加功能,光标将允许您按名称访问列,这就是您最终的目的传递给模板。 得到这个解释:How can I reference columns by their names in python calling SQLite?

【讨论】:

  • 1.您正在使用哪个数据库,它可以帮助检查语法?您是否成功地直接针对 db 运行查询? 2. 如果处理不正确,您的列 (branche_id) 有歧义,可能会导致头痛,如果可以的话,为了测试,我会在每个表中将其重命名为不同的名称,以避免歧义。
  • 我使用 SQLite 作为数据库,你说的是哪个查询?没有指向branche 表的任何链接,一切正常,这时我想包含一个参考,以便在其他contact 信息旁边显示branche 名称
  • 我想我发现你是拼写错误,在模板中你应该用contact['branche_nom']替换branche['branche_nom'],因为你正在迭代已经有的联系人列 branche_nom 但您为每一行使用联系人,而不是分支。
  • 感谢您的解释,我知道问题出在哪里,但我不知道如何解决;我添加了包含 db 加载的 db.py 文件,并且在 html 文件中,循环 for contact in contacts 根本不起作用,contacts 是就像 =NULL,我的 db.execute 函数有什么问题?还是其他功能有问题?
  • 最重要的代码是 db.row_factory = sqlite3.Row ,因为它使用您可以使用的列名包装获取的游标。只是为了测试尝试读取光标并遍历列,没有这行代码你将只能通过索引号访问,而使用此代码你可以通过名称访问它。
猜你喜欢
  • 2018-10-29
  • 1970-01-01
  • 2021-10-09
  • 1970-01-01
  • 2016-03-25
  • 1970-01-01
  • 2017-09-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多