Python操作國產金倉數(shù)據庫KingbaseES全流程
前言
現(xiàn)在國產化替代是大趨勢,國產數(shù)據庫的應用范圍越來越廣,金倉數(shù)據庫(KingbaseES)作為其中的佼佼者,在政務、金融等領域部署得特別多。今天我就帶大家從0到1,親手實現(xiàn)用Python操作KingbaseES數(shù)據庫,還會基于Flask框架搭一個可視化的網頁管理系統(tǒng),數(shù)據的增刪改查(CRUD)全流程都能覆蓋到,Python開發(fā)者和數(shù)據庫管理員跟著學,都能掌握這套實用技能。
一、前置知識與環(huán)境準備
開始動手前,咱們得把相關的環(huán)境和工具準備好,這樣后面開發(fā)的時候才不會卡殼。
1.1 核心技術棧
這次做項目用的技術都不復雜,也不用復雜的框架,輕量化還好上手,具體有這些:
- 后端框架:Flask(這是個輕量級的Python Web框架,用來快速搭網頁服務特別方便)
- 數(shù)據庫驅動:psycopg2(KingbaseES兼容PostgreSQL協(xié)議,直接用這個驅動就能連接數(shù)據庫)
- 前端技術:HTML + 原生CSS(不用額外學前端框架,咱們把核心功能實現(xiàn)了就行)
- 數(shù)據庫:KingbaseES V8/R3(我這次用的是比較常見的版本,其他版本操作步驟都一樣)
1.2 環(huán)境安裝步驟
步驟1:安裝Python(已經裝了的話這步就跳過)
直接去Python官網下載3.7及以上版本,安裝的時候記得勾選“Add Python to PATH”,這樣后面在命令行里就能直接調用python和pip命令了。
步驟2:安裝依賴庫
打開命令行,輸下面這些命令,就能把項目需要的依賴庫裝好:
# 安裝Flask框架 pip install flask # 安裝KingbaseES數(shù)據庫驅動(兼容PostgreSQL) pip install psycopg2-binary
步驟3:確認KingbaseES數(shù)據庫狀態(tài)
- 首先得確保KingbaseES數(shù)據庫已經啟動了,而且能通過IP(比如本地的
127.0.0.1)和端口(默認常用端口是54321)訪問到。 - 提前創(chuàng)建好數(shù)據庫,我這次用的是
TEST庫,大家可以用KingbaseES的圖形化工具KingbaseManager來創(chuàng)建。 - 還要準備好數(shù)據庫的賬號密碼,我這里用的是默認管理員賬號
system,密碼大家可以自己修改。
二、項目架構設計
為了讓代碼結構清晰,后面維護起來也方便,咱們采用“后端邏輯+前端模板”的分層設計,整個項目的目錄結構是這樣的:
kingbase_web_manager/ # 項目根目錄
├── app.py # 后端核心邏輯(包含F(xiàn)lask服務、數(shù)據庫操作、路由定義)
└── templates/ # 前端HTML模板文件夾(用繼承式設計,減少重復代碼)
├── base.html # 基礎模板(放公共頭部、樣式、消息提示這些)
├── index.html # 首頁(用來展示用戶列表)
├── init_schema.html # 表結構初始化頁面
├── create_user.html # 新增用戶頁面
├── user_detail.html # 用戶詳情頁面
└── update_balance.html # 余額修改頁面
- 后端:通過Flask定義路由,處理前端發(fā)來的HTTP請求,再調用
psycopg2去操作KingbaseES數(shù)據庫。 - 前端:用HTML模板繼承的方式,
base.html作為父模板,這樣所有頁面風格能統(tǒng)一,也能少寫很多重復代碼。
三、后端核心實現(xiàn)(app.py)
后端就像是整個系統(tǒng)的“大腦”,負責連接數(shù)據庫、處理業(yè)務邏輯,最后把數(shù)據返回給前端。下面我分模塊給大家講核心代碼怎么寫。
3.1 初始化Flask與數(shù)據庫配置
首先創(chuàng)建app.py文件,先把Flask應用初始化好,再配置KingbaseES數(shù)據庫的連接參數(shù):
from flask import Flask, jsonify, request, render_template, redirect, url_for, flash
import psycopg2 # KingbaseES數(shù)據庫驅動
import psycopg2.extras as extras # 擴展功能(如DictCursor,讓查詢結果為字典格式)
# 初始化Flask應用
app = Flask(__name__)
# 配置secret_key(用于flash消息提示,防止跨站請求偽造)
app.secret_key = 'kingbase_web_manager_2024'
# --------------------------
# KingbaseES數(shù)據庫連接配置
# --------------------------
DB_CFG = dict(
host="127.0.0.1", # 數(shù)據庫IP(本地為127.0.0.1,遠程需填實際IP)
port=54321, # KingbaseES默認常見端口(不同環(huán)境可能為5432,需確認)
dbname="TEST", # 數(shù)據庫名稱(提前創(chuàng)建好)
user="system", # 數(shù)據庫賬號(管理員賬號)
password="jcsjk520.",# 數(shù)據庫密碼(替換為你的實際密碼)
connect_timeout=5, # 連接超時時間(5秒)
)
# --------------------------
# 數(shù)據庫連接工具函數(shù)
# --------------------------
def get_conn():
"""獲取KingbaseES數(shù)據庫連接"""
try:
# 使用psycopg2.connect連接數(shù)據庫,**DB_CFG表示解包配置字典
conn = psycopg2.connect(**DB_CFG)
return conn
except Exception as e:
# 連接失敗時拋出異常(后續(xù)路由會捕獲處理)
raise Exception(f"數(shù)據庫連接失敗: {str(e)}")
3.2 表結構初始化(建表)
第一次用的時候,得先創(chuàng)建用戶表(t_user),咱們可以通過/init-schema這個路由,在網頁端觸發(fā)建表操作:
@app.route('/init-schema', methods=['GET', 'POST'])
def init_schema():
"""初始化用戶表結構(GET請求顯示頁面,POST請求執(zhí)行建表)"""
# 1. POST請求:用戶點擊"初始化"按鈕,執(zhí)行建表SQL
if request.method == 'POST':
# 定義建表SQL(if not exists確保表不存在時才創(chuàng)建,避免重復執(zhí)行報錯)
create_table_sql = """
create table if not exists t_user(
id serial primary key, # 自增主鍵(用戶ID)
name varchar(64) not null, # 用戶名(非空)
balance numeric(12,2) default 0, # 余額(默認0,支持兩位小數(shù))
created_at timestamp default current_timestamp # 創(chuàng)建時間(默認當前時間)
);
"""
try:
# 使用with語句自動管理連接和游標(無需手動關閉)
with get_conn() as conn, conn.cursor() as cur:
cur.execute(create_table_sql) # 執(zhí)行建表SQL
# 建表成功,通過flash傳遞成功消息(前端會顯示)
flash('表結構初始化成功!', 'success')
except Exception as e:
# 建表失敗,傳遞錯誤消息
flash(f'初始化失敗: {str(e)}', 'danger')
# 無論成功與否,跳轉回首頁
return redirect(url_for('index'))
# 2. GET請求:顯示初始化表結構的頁面
return render_template('init_schema.html')
3.3 用戶數(shù)據增刪改查實現(xiàn)
接下來咱們實現(xiàn)核心的CRUD功能,每個功能對應一個路由,專門處理前端的請求,然后操作數(shù)據庫。
3.3.1 首頁:展示所有用戶(查-列表)
首頁/這個路由會查詢t_user表里的所有數(shù)據,然后把數(shù)據傳給前端模板展示出來:
@app.route('/')
def index():
"""首頁:展示所有用戶列表"""
try:
# 查詢所有用戶數(shù)據(按ID升序,可選)
query_sql = "select id, name, balance, created_at from t_user order by id;"
# 使用DictCursor,讓查詢結果為字典(便于前端通過鍵名獲取值)
with get_conn() as conn, conn.cursor(cursor_factory=extras.DictCursor) as cur:
cur.execute(query_sql)
# fetchall()獲取所有結果,轉換為列表(每個元素是字典)
users = [dict(row) for row in cur.fetchall()]
# 渲染首頁模板,傳遞用戶列表數(shù)據
return render_template('index.html', users=users)
except Exception as e:
# 查詢失敗,顯示錯誤消息,傳遞空列表
flash(f'數(shù)據庫查詢錯誤: {str(e)}', 'danger')
return render_template('index.html', users=[])
3.3.2 新增用戶(增)
通過/user/create這個路由實現(xiàn)新增用戶的功能,還能讓用戶輸入用戶名和初始余額:
@app.route('/user/create', methods=['GET', 'POST'])
def create_user():
"""新增用戶(GET顯示表單,POST提交數(shù)據)"""
if request.method == 'POST':
# 1. 獲取前端表單提交的數(shù)據(request.form用于獲取POST表單數(shù)據)
name = request.form.get('name') # 用戶名(必填)
balance = request.form.get('balance', 0.0) # 初始余額(可選,默認0)
# 2. 數(shù)據校驗:用戶名不能為空
if not name:
flash('用戶名不能為空!', 'danger')
return render_template('create_user.html') # 校驗失敗,返回表單頁面
try:
# 3. 數(shù)據格式轉換:余額轉為浮點數(shù)(防止非數(shù)字輸入)
balance = float(balance) if balance else 0.0
# 4. 執(zhí)行插入SQL(returning id返回新增用戶的ID)
insert_sql = "insert into t_user(name, balance) values (%s, %s) returning id;"
with get_conn() as conn, conn.cursor() as cur:
cur.execute(insert_sql, (name, balance)) # %s為參數(shù)占位符(防止SQL注入)
user_id = cur.fetchone()[0] # 獲取返回的用戶ID
# 5. 新增成功,跳轉回首頁
flash(f'用戶創(chuàng)建成功!用戶ID: {user_id}', 'success')
return redirect(url_for('index'))
except ValueError:
# 余額非數(shù)字時捕獲異常
flash('初始余額必須為數(shù)字!', 'danger')
except Exception as e:
# 其他錯誤(如數(shù)據庫異常)
flash(f'用戶創(chuàng)建失敗: {str(e)}', 'danger')
# GET請求:顯示新增用戶表單
return render_template('create_user.html')
3.3.3 查看用戶詳情(查-單條)
通過用戶ID查詢單條用戶數(shù)據,然后展示詳細信息:
@app.route('/user/<int:user_id>')
def get_user(user_id):
"""查看單個用戶詳情(通過URL路徑傳遞user_id)"""
try:
# 查詢指定ID的用戶數(shù)據
query_sql = "select id, name, balance, created_at from t_user where id=%s;"
with get_conn() as conn, conn.cursor(cursor_factory=extras.DictCursor) as cur:
cur.execute(query_sql, (user_id,)) # 傳遞user_id參數(shù)
user = dict(cur.fetchone()) if cur.rowcount > 0 else None # 轉換為字典
# 校驗用戶是否存在
if not user:
flash('該用戶不存在!', 'danger')
return redirect(url_for('index')) # 不存在則跳轉回首頁
# 渲染詳情頁面,傳遞用戶數(shù)據
return render_template('user_detail.html', user=user)
except Exception as e:
flash(f'查詢用戶失敗: {str(e)}', 'danger')
return redirect(url_for('index'))
3.3.4 修改用戶余額(改)
通過/user/<user_id>/balance這個路由調整用戶余額,不管是增加還是減少都能實現(xiàn):
@app.route('/user/<int:user_id>/balance', methods=['GET', 'POST'])
def update_balance(user_id):
"""修改用戶余額(GET顯示表單,POST提交修改)"""
if request.method == 'POST':
try:
# 1. 獲取余額變動值(delta:正數(shù)增加,負數(shù)減少)
delta = float(request.form.get('delta', 0))
# 2. 執(zhí)行更新SQL(balance = balance + %s 實現(xiàn)增量更新)
update_sql = "update t_user set balance = balance + %s where id=%s;"
with get_conn() as conn, conn.cursor() as cur:
cur.execute(update_sql, (delta, user_id))
# 校驗用戶是否存在(rowcount為受影響行數(shù),0表示無此用戶)
if cur.rowcount == 0:
flash('該用戶不存在!', 'danger')
return redirect(url_for('index'))
# 3. 更新成功,跳轉回用戶詳情頁
flash('余額更新成功!', 'success')
return redirect(url_for('get_user', user_id=user_id))
except ValueError:
# 變動值非數(shù)字時捕獲異常
flash('余額變動值必須為數(shù)字!', 'danger')
except Exception as e:
flash(f'余額更新失敗: {str(e)}', 'danger')
# GET請求:顯示余額修改表單(先查詢當前用戶信息)
try:
query_sql = "select id, name, balance from t_user where id=%s;"
with get_conn() as conn, conn.cursor(cursor_factory=extras.DictCursor) as cur:
cur.execute(query_sql, (user_id,))
user = dict(cur.fetchone()) if cur.rowcount > 0 else None
if not user:
flash('該用戶不存在!', 'danger')
return redirect(url_for('index'))
# 渲染修改余額表單,傳遞當前用戶信息
return render_template('update_balance.html', user=user)
except Exception as e:
flash(f'查詢用戶信息失敗: {str(e)}', 'danger')
return redirect(url_for('index'))
3.3.5 刪除用戶(刪)
通過/user/<user_id>/delete這個路由刪除指定用戶,為了防止誤刪,還得讓用戶確認一下操作:
@app.route('/user/<int:user_id>/delete', methods=['POST'])
def delete_user(user_id):
"""刪除用戶(僅支持POST請求,避免GET請求誤觸發(fā))"""
try:
# 執(zhí)行刪除SQL
delete_sql = "delete from t_user where id=%s;"
with get_conn() as conn, conn.cursor() as cur:
cur.execute(delete_sql, (user_id,))
if cur.rowcount == 0:
flash('該用戶不存在!', 'danger')
else:
flash('用戶刪除成功!', 'success')
except Exception as e:
flash(f'用戶刪除失敗: {str(e)}', 'danger')
# 刪除后跳轉回首頁
return redirect(url_for('index'))
# --------------------------
# 啟動Flask服務
# --------------------------
if __name__ == '__main__':
# debug=True:開發(fā)模式(代碼修改后自動重啟,錯誤信息顯示在網頁上)
app.run(debug=True)
四、前端模板實現(xiàn)(templates文件夾)
前端咱們用“繼承式模板”來設計,base.html里定義公共的樣式和頁面結構,其他模板都繼承它,這樣能少寫很多重復代碼。
4.1 基礎模板(base.html)
所有頁面的公共部分,像頭部標題、樣式、消息提示這些,都放在這個模板里:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kingbase用戶管理系統(tǒng)</title>
<!-- 公共CSS樣式(統(tǒng)一頁面風格) -->
<style>
.container { max-width: 1200px; margin: 0 auto; padding: 20px; }
.flash { padding: 12px; margin: 15px 0; border-radius: 4px; font-size: 14px; }
.success { background-color: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
.danger { background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }
table { width: 100%; border-collapse: collapse; margin: 20px 0; }
th, td { padding: 12px 15px; border: 1px solid #ddd; text-align: left; }
th { background-color: #f8f9fa; font-weight: bold; }
tr:hover { background-color: #f8f9fa; }
.btn { display: inline-block; padding: 8px 16px; margin: 0 5px; text-decoration: none;
color: #fff; border-radius: 4px; border: none; cursor: pointer; font-size: 14px; }
.btn-primary { background-color: #007bff; }
.btn-success { background-color: #28a745; }
.btn-danger { background-color: #dc3545; }
.form-group { margin-bottom: 20px; }
label { display: block; margin-bottom: 8px; font-weight: bold; }
input { padding: 10px; width: 350px; border: 1px solid #ddd; border-radius: 4px;
font-size: 14px; box-sizing: border-box; }
h1, h2 { color: #333; margin-bottom: 20px; }
.operate-btn-group { margin: 20px 0; }
</style>
</head>
<body>
<div class="container">
<!-- 頁面標題(點擊可返回首頁) -->
<h1><a href="/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" style="text-decoration: none; color: #333;">Kingbase用戶管理系統(tǒng)</a></h1>
<!-- 消息提示區(qū)域(顯示success/danger消息) -->
<div>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="flash {{ category }}">{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
</div>
<!-- 子模板內容區(qū)域(由其他頁面填充) -->
{% block content %}{% endblock %}
</div>
</body>
</html>
4.2 首頁模板(index.html)
這個模板繼承base.html,主要用來展示用戶列表和操作按鈕:
{% extends "base.html" %} <!-- 繼承基礎模板 -->
{% block content %} <!-- 填充content區(qū)域 -->
<!-- 操作按鈕組(初始化表結構、新增用戶) -->
<div class="operate-btn-group">
<a href="/init-schema" rel="external nofollow" class="btn btn-primary">初始化表結構</a>
<a href="/user/create" rel="external nofollow" class="btn btn-success">添加新用戶</a>
</div>
<!-- 用戶列表標題 -->
<h2>用戶列表</h2>
<!-- 若有用戶數(shù)據,展示表格;否則提示無數(shù)據 -->
{% if users %}
<table>
<tr>
<th>用戶ID</th>
<th>用戶名</th>
<th>賬戶余額(元)</th>
<th>創(chuàng)建時間</th>
<th>操作</th>
</tr>
{% for user in users %} <!-- 循環(huán)遍歷用戶列表 -->
<tr>
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td>{{ user.balance }}</td>
<td>{{ user.created_at }}</td>
<td>
<!-- 查看詳情按鈕 -->
<a href="/user/{{ user.id }}" rel="external nofollow" rel="external nofollow" class="btn btn-primary">查看</a>
<!-- 調整余額按鈕 -->
<a href="/user/{{ user.id }}/balance" rel="external nofollow" rel="external nofollow" class="btn btn-success">調整余額</a>
<!-- 刪除按鈕(POST請求,需用表單包裹) -->
<form action="/user/{{ user.id }}/delete" method="post" style="display: inline;">
<button type="submit" class="btn btn-danger"
onclick="return confirm('確定要刪除該用戶嗎?刪除后不可恢復!')">
刪除
</button>
</form>
</td>
</tr>
{% endfor %}
</table>
{% else %}
<p style="color: #666; font-size: 16px;">暫無用戶數(shù)據,請先初始化表結構并添加用戶。</p>
{% endif %}
{% endblock %}

4.3 表結構初始化模板(init_schema.html)
這個模板提供一個初始化表結構的確認按鈕,點擊就能觸發(fā)建表:
{% extends "base.html" %}
{% block content %}
<h2>初始化用戶表結構</h2>
<p style="font-size: 16px; margin: 20px 0;">
點擊下方按鈕創(chuàng)建用戶表(t_user),若表已存在則不會重復創(chuàng)建。
</p>
<!-- 提交表單(POST請求觸發(fā)建表) -->
<form method="post">
<button type="submit" class="btn btn-success">確認初始化表結構</button>
<a href="/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="btn btn-primary">返回首頁</a>
</form>
{% endblock %}

4.4 新增用戶模板(create_user.html)
這里有個表單,用戶可以輸入用戶名和初始余額,用來新增用戶:
{% extends "base.html" %}
{% block content %}
<h2>添加新用戶</h2>
<form method="post">
<!-- 用戶名輸入框(必填) -->
<div class="form-group">
<label for="name">用戶名 <span style="color: red;">*</span></label>
<input type="text" id="name" name="name" required
placeholder="請輸入用戶名(如:張三)">
</div>
<!-- 初始余額輸入框(可選) -->
<div class="form-group">
<label for="balance">初始余額(元)</label>
<input type="number" id="balance" name="balance" step="0.01" min="0"
placeholder="請輸入數(shù)字(默認0,如:100.50)">
</div>
<!-- 提交與返回按鈕 -->
<button type="submit" class="btn btn-success">創(chuàng)建用戶</button>
<a href="/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="btn btn-primary">返回首頁</a>
</form>
{% endblock %}

4.5 用戶詳情模板(user_detail.html)
這個模板用來展示單個用戶的詳細信息,看得更清楚:
{% extends "base.html" %}
{% block content %}
<h2>用戶詳情</h2>
{% if user %}
<table>
<tr>
<th style="width: 150px;">用戶ID</th>
<td>{{ user.id }}</td>
</tr>
<tr>
<th>用戶名</th>
<td>{{ user.name }}</td>
</tr>
<tr>
<th>賬戶余額(元)</th>
<td>{{ user.balance }}</td>
</tr>
<tr>
<th>創(chuàng)建時間</th>
<td>{{ user.created_at }}</td>
</tr>
</table>
<!-- 操作按鈕 -->
<div class="operate-btn-group">
<a href="/user/{{ user.id }}/balance" rel="external nofollow" rel="external nofollow" class="btn btn-success">調整余額</a>
<a href="/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="btn btn-primary">返回用戶列表</a>
</div>
{% endif %}
{% endblock %}

4.6 余額修改模板(update_balance.html)
這里有個輸入框,用戶可以輸入余額變動值,用來調整用戶余額:
{% extends "base.html" %}
{% block content %}
<h2>調整用戶余額</h2>
{% if user %}
<!-- 顯示當前用戶信息 -->
<p style="font-size: 16px; margin: 10px 0;">
當前用戶:<strong>{{ user.name }}</strong>(ID:{{ user.id }})
</p>
<p style="font-size: 16px; margin: 10px 0;">
當前余額:<strong>{{ user.balance }} 元</strong>
</p>
<!-- 余額變動表單 -->
<form method="post">
<div class="form-group">
<label for="delta">余額變動值(元)</label>
<input type="number" id="delta" name="delta" step="0.01" required
placeholder="正數(shù)增加,負數(shù)減少(如:50.00 或 -20.50)">
<small style="color: #666; display: block; margin-top: 5px;">
提示:輸入正數(shù)表示增加余額,輸入負數(shù)表示減少余額(如輸入-10表示減少10元)
</small>
</div>
<!-- 提交與返回按鈕 -->
<button type="submit" class="btn btn-success">確認更新</button>
<a href="/user/{{ user.id }}" rel="external nofollow" rel="external nofollow" class="btn btn-primary">返回詳情</a>
</form>
{% endif %}
{% endblock %}

五、系統(tǒng)運行與測試
代碼都寫完之后,咱們就可以啟動系統(tǒng),測試一下功能能不能正常用了。
5.1 啟動步驟
- 首先得確保KingbaseES數(shù)據庫已經啟動了,而且DB_CFG里配置的IP、端口、賬號密碼都是對的。
- 找到項目根目錄(就是app.py所在的文件夾),打開命令行,輸入下面這個命令:
python app.py
- 看到下面這樣的輸出,就說明Flask服務啟動成功了:
* Serving Flask app 'app' * Debug mode: on WARNING: This is a development server. Do not use it in a production deployment. * Running on http://127.0.0.1:5000 Press CTRL+C to quit
5.2 功能測試流程
步驟1:初始化表結構
- 打開瀏覽器,訪問
http://127.0.0.1:5000,點擊“初始化表結構”按鈕,頁面會提示“表結構初始化成功”。 - 這時候大家可以用KingbaseManager工具查一下,
TEST庫里已經創(chuàng)建好t_user表了。
步驟2:新增用戶
- 點擊頁面上的“添加新用戶”,輸入用戶名(比如“張三”),再填個初始余額(比如“200”),然后點擊“創(chuàng)建用戶”,頁面會提示“用戶創(chuàng)建成功”。
- 回到首頁,就能看到剛才新增的用戶數(shù)據了。
步驟3:查看用戶詳情
- 找到剛才新增的用戶,點擊用戶那一行的“查看”按鈕,就能進入詳情頁,用戶的ID、姓名、余額、創(chuàng)建時間都能看到。
步驟4:修改用戶余額
- 在詳情頁點擊“調整余額”,輸入變動值(比如“50”,意思是增加50元),然后點擊“確認更新”,頁面會提示“余額更新成功”。
- 再回到詳情頁,就會發(fā)現(xiàn)余額已經變成250元了。
步驟5:刪除用戶
- 回到首頁,找到要刪除的用戶,點擊“刪除”按鈕,會彈出一個確認框,點擊“確定”,頁面提示“用戶刪除成功”。
- 這時候首頁就不會再顯示這個用戶的數(shù)據了。
六、常見問題與解決方案
開發(fā)和測試的時候,大家可能會遇到一些問題,我整理了幾個常見的,還給出了對應的解決辦法:
6.1 數(shù)據庫連接失敗
- 錯誤提示:
數(shù)據庫連接失敗: could not connect to server: Connection refused - 原因:要么是KingbaseES數(shù)據庫沒啟動,要么是IP或者端口配置錯了。
- 解決方案:
- 先檢查KingbaseES服務有沒有啟動,可以通過服務管理器或者
sys_ctl命令來查看。 - 確認一下
DB_CFG里的host(遠程的話要填實際IP,本地就是127.0.0.1)和port(默認是54321,有些環(huán)境可能是5432)對不對。 - 還要確保數(shù)據庫賬號密碼是對的,而且
system賬號有操作TEST庫的權限。
- 先檢查KingbaseES服務有沒有啟動,可以通過服務管理器或者
6.2 建表失敗
- 錯誤提示:
初始化失敗: permission denied for schema public - 原因:
system賬號對public模式沒有創(chuàng)建表的權限。 - 解決方案:
- 用KingbaseManager登錄
TEST庫,執(zhí)行下面這個授權SQL:
- 用KingbaseManager登錄
grant create on schema public to system;
執(zhí)行完之后,再重新做一次初始化操作就行。
6.3 余額修改時提示“非數(shù)字”
- 錯誤提示:
余額變動值必須為數(shù)字! - 原因:在輸入余額變動值的時候,里面混了非數(shù)字字符,比如字母、中文這些。
- 解決方案:輸入的時候注意一下,只填數(shù)字、小數(shù)點(比如“30.5”)或者負號(比如“-10”)就可以了。
七、項目擴展建議
這個項目目前實現(xiàn)了基礎的用戶管理功能,大家可以根據自己的實際需求再擴展一下,比如這些方向:
- 用戶認證:加個登錄功能(可以用Flask-Login),這樣能防止沒授權的人隨便訪問系統(tǒng)。
- 分頁查詢:要是用戶數(shù)據特別多,在首頁加個分頁功能會更方便,用SQL的
limit和offset就能實現(xiàn)。 - 數(shù)據校驗:新增用戶的時候,加個用戶名唯一性校驗,先查一下數(shù)據庫里有沒有重名的,避免重復創(chuàng)建。
- 日志記錄:用
logging模塊記錄數(shù)據庫的操作日志,后面要是出了問題,排查起來會更方便。 - 生產環(huán)境部署:要是要放到生產環(huán)境用,記得把
debug模式關掉,用Gunicorn當WSGI服務器,再配個Nginx做反向代理,這樣更穩(wěn)定。
八、總結
這篇文章從環(huán)境準備、架構設計、代碼實現(xiàn)到功能測試,把用Python操作KingbaseES數(shù)據庫,還有搭網頁管理系統(tǒng)的過程都講清楚了。咱們用Flask框架和psycopg2驅動,實現(xiàn)了數(shù)據增刪改查的全流程,前端用原生HTML/CSS,頁面簡單又好用。
希望這篇文章能幫大家快速掌握用Python操作國產數(shù)據庫的技巧,給國產化項目開發(fā)提供點參考。
以上就是Python操作國產金倉數(shù)據庫KingbaseES全流程的詳細內容,更多關于Python操作數(shù)據庫KingbaseES的資料請關注腳本之家其它相關文章!
相關文章
python為tornado添加recaptcha驗證碼功能
tornado作為微框架,并沒有自帶驗證碼組件,recaptcha是著名的驗證碼解決方案,簡單易用,被很多公司運用來防止惡意注冊和評論。tornado添加recaptchaHA非常容易2014-02-02
keras 自定義loss model.add_loss的使用詳解
這篇文章主要介紹了keras 自定義loss model.add_loss的使用詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06
在VS Code上搭建Python開發(fā)環(huán)境的方法
這篇文章主要介紹了在VS Code上搭建Python開發(fā)環(huán)境的方法,需要的朋友可以參考下2018-04-04
Python中staticmethod和classmethod的作用與區(qū)別
今天小編就為大家分享一篇關于Python中staticmethod和classmethod的作用與區(qū)別,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-10-10

