【Python使用】嘿馬頭條完整開發md筆記第2篇:資料庫,作用【附程式碼文件】

程序员一诺yinuo發表於2024-03-18

嘿馬頭條專案從到完整開發筆記總結完整教程(附程式碼資料)主要內容講述:課程簡介,ToutiaoWeb虛擬機器使用說明,Pycharm遠端開發,產品與開發,資料庫1 產品介紹,2 原型圖與UI圖,3 技術架構,4 開發。OSS物件儲存,七牛雲端儲存,CDN,快取。快取,快取架構,快取資料,快取有效期與淘汰策略,快取模式快取資料的型別,快取資料的儲存方式,有效期 TTL (Time to live),快取淘汰 eviction。快取,快取問題,頭條專案快取與儲存設計,頭條專案快取實現,專案Redis持久儲存實現,APScheduler定時任務,APScheduler使用1 快取穿透,2 快取雪崩,快取設計,持久儲存設計。APScheduler定時任務,定時修正統計資料,RPC,RPC簡介,RPC結構,gRPC,簡介1. 什麼是RPC,2. 背景與用途,3. 概念說明,4. 優缺點,架構,使用方法。RPC,Protocol Buffers,推薦系統介面定義,補全服務端1 文件結構,2 註釋,3 資料型別,4 訊息型別,5 map對映,6 oneof,7 定義服務,程式碼生成。RPC,編寫客戶端,頭條首頁新聞推薦介面編寫,即時通訊,即時通訊簡介,WebSocket。即時通訊,Socket.IO,頭條聊天服務實現,頭條線上訊息推送實現,Elasticsearch1 簡介,2 Python伺服器端開發,3 Python客戶端。Elasticsearch,簡介與原理。Elasticsearch,概念與叢集,IK中文分析器,索引與型別概念,Elasticsearch 叢集(cluster),索引,型別和對映。Elasticsearch,文件,Logstash匯入資料,查詢,頭條全文檢索實現,聯想提示,頭條suggest查詢實現。資料庫,資料庫設計1 需求,2 注意事項,3 頭條專案資料庫。單元測試,部署相關,Gunicorn,Supervisor。資料庫,理解ORM,SQLAlchemy對映構建1 簡介,2 安裝,3 資料庫連線設定,4 模型類欄位與選項,5 構建模型類對映。資料庫,SQLAlchemy操作1 新增,2 查詢,3 更新,4 刪除,5 事務。資料庫,資料庫理論1. 複製集與分散式,2. MySQL。資料庫,分散式ID,資料庫最佳化1 方案選擇,2 黑馬頭條,1 理解索引,2 SQL查詢最佳化,3 資料庫最佳化。資料庫,Redis,Git工用流1 Redis事務,2 Redis持久化,3 Redis高可用,4 Redis叢集,5 用途,6 相關補充閱讀。Git工用流,Gitflow工作流,Git總結,頭條專案目錄1 Gitflow工作流分支,2 Confict衝突解決。Git工用流,除錯方法,JWT認證方案,JWT & JWS & JWE,JWT的Python庫,頭條專案實施方案,JWT禁用問題,OSS物件儲存。

全套筆記資料程式碼移步: 前往gitee倉庫檢視

感興趣的小夥伴可以自取哦,歡迎大家點贊轉發~


全套教程部分目錄:


部分檔案圖片:

資料庫

  • 資料庫設計

  • SQLAlchemy

  • 資料庫理論

  • 分散式ID

  • Redis

理解ORM

orm

作用

  • 省去自己拼寫SQL,保證SQL語法的正確性

  • 一次編寫可以適配多個資料庫

  • 防止注入

  • 在資料庫表名或欄位名發生變化時,只需修改模型類的對映,無需修改資料庫操作的程式碼

(相比SQL的話,可能需要同步修改涉及到的每一個SQL語句)

思考:

可否在已經存在資料庫表的情況下,使用模型類進行操作?

what

使用ORM的方式選擇

  1. 先建立模型類,再遷移到資料庫中

    • 優點:簡單快捷,定義一次模型類即可,不用寫sql
    • 缺點:不能盡善盡美的控制建立表的所有細節問題,表結構發生變化的時候,也會難免發生遷移錯誤
  2. 先用原生SQL建立資料庫表,再編寫模型類作對映

    • 優點:可以很好的控制資料庫表結構的任何細節,避免發生遷移錯誤
    • 缺點:可能編寫工作多(編寫sql與模型類,似乎有些牽強)

頭條專案採用編寫原生SQL建立表,之後再編寫模型類進行對映的方式。

SQLAlchemy對映構建

1 簡介

SQLAlchemy是Python程式語言下的一款開源軟體。提供了SQL工具包及物件關係對映(ORM)工具,使用MIT許可證發行。

SQLAlchemy“採用簡單的Python語言,為高效和高效能的資料庫訪問設計,實現了完整的企業級持久模型”。

SQLAlchemy首次發行於2006年2月,並迅速地在Python社群中最廣泛使用的ORM工具之一,不亞於Django的ORM框架。

Flask-SQLAlchemy是在Flask框架的一個擴充套件,其對SQLAlchemy進行了封裝,目的於簡化在 Flask 中 SQLAlchemy 的 使用,提供了有用的預設值和額外的助手來更簡單地完成日常任務。

2 安裝

安裝Flask-SQLAlchemy

pip install flask-sqlalchemy

如果使用的是MySQL資料庫,還需要安裝MySQL的Python客戶端庫

pip install mysqlclient

3 資料庫連線設定

在Flask中使用Flask-SQLAlchemy需要進行配置,主要配置以下幾項:

  • SQLALCHEMY_DATABASE_URI 資料庫的連線資訊

    • Postgres:

postgresql://user:password@localhost/mydatabase




* MySQL:

```python
mysql://user:password@localhost/mydatabase
  • Oracle:
oracle://user:password@127.0.0.1:1521/sidname
  • SQLite (注意開頭的四個斜線):
sqlite:////absolute/path/to/foo.db
  • SQLALCHEMY_TRACK_MODIFICATIONS 在Flask中是否追蹤資料修改

  • SQLALCHEMY_ECHO 顯示生成的SQL語句,可用於除錯

這些配置引數需要放在Flask的應用配置(app.config)中。

from flask import Flask

app = Flask(__name__)

class Config(object):
    SQLALCHEMY_DATABASE_URI = 'mysql://root:mysql@127.0.0.1:3306/toutiao'
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    SQLALCHEMY_ECHO = True

app.config.from_object(Config)

其他配置參考如下:

名字 備註
SQLALCHEMY_DATABASE_URI 用於連線的資料庫 URI 。例如:sqlite:////tmp/test.dbmysql://username:password@server/db
SQLALCHEMY_BINDS 一個對映 binds 到連線 URI 的字典。更多 binds 的資訊見[用 Binds 操作多個資料庫](
SQLALCHEMY_ECHO 如果設定為Ture, SQLAlchemy 會記錄所有 發給 stderr 的語句,這對除錯有用。(列印sql語句)
SQLALCHEMY_RECORD_QUERIES 可以用於顯式地禁用或啟用查詢記錄。查詢記錄 在除錯或測試模式自動啟用。更多資訊見get_debug_queries()。
SQLALCHEMY_NATIVE_UNICODE 可以用於顯式禁用原生 unicode 支援。當使用 不合適的指定無編碼的資料庫預設值時,這對於 一些資料庫介面卡是必須的(比如 Ubuntu 上 某些版本的 PostgreSQL )。
SQLALCHEMY_POOL_SIZE 資料庫連線池的大小。預設是引擎預設值(通常 是 5 )
SQLALCHEMY_POOL_TIMEOUT 設定連線池的連線超時時間。預設是 10 。
SQLALCHEMY_POOL_RECYCLE 多少秒後自動回收連線。這對 MySQL 是必要的, 它預設移除閒置多於 8 小時的連線。注意如果 使用了 MySQL , Flask-SQLALchemy 自動設定 這個值為 2 小時。

4 模型類欄位與選項

欄位型別

型別名 python中型別 說明
Integer int 普通整數,一般是32位
SmallInteger int 取值範圍小的整數,一般是16位
BigInteger int或long 不限制精度的整數
Float float 浮點數
Numeric decimal.Decimal 普通整數,一般是32位
String str 變長字串
Text str 變長字串,對較長或不限長度的字串做了最佳化
Unicode unicode 變長Unicode字串
UnicodeText unicode 變長Unicode字串,對較長或不限長度的字串做了最佳化
Boolean bool 布林值
Date datetime.date 時間
Time datetime.datetime 日期和時間
LargeBinary str 二進位制檔案

列選項

選項名 說明
primary_key 如果為True,代表表的主鍵
unique 如果為True,代表這列不允許出現重複的值
index 如果為True,為這列建立索引,提高查詢效率
nullable 如果為True,允許有空值,如果為False,不允許有空值
default 為這列定義預設值

關係選項

選項名 說明
backref 在關係的另一模型中新增反向引用
primary join 明確指定兩個模型之間使用的聯結條件
uselist 如果為False,不使用列表,而使用標量值
order_by 指定關係中記錄的排序方式
secondary 指定多對多關係中關係表的名字
secondary join 在SQLAlchemy中無法自行決定時,指定多對多關係中的二級聯結條件

5 構建模型類對映

例用虛擬機器中已有的頭條資料庫,構建模型類對映,以下面三張表為例

CREATE TABLE `user_basic` (
  `user_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '使用者ID',
  `account` varchar(20) COMMENT '賬號',
  `email` varchar(20) COMMENT '郵箱',
  `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '狀態,是否可用,0-不可用,1-可用',
  `mobile` char(11) NOT NULL COMMENT '手機號',
  `password` varchar(93) NULL COMMENT '密碼',
  `user_name` varchar(32) NOT NULL COMMENT '暱稱',
  `profile_photo` varchar(128) NULL COMMENT '頭像',
  `last_login` datetime NULL COMMENT '最後登入時間',
  `is_media` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否是自媒體,0-不是,1-是',
  `is_verified` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否實名認證,0-不是,1-是',
  `introduction` varchar(50) NULL COMMENT '簡介',
  `certificate` varchar(30) NULL COMMENT '認證',
  `article_count` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '發文章數',
  `following_count` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '關注的人數',
  `fans_count` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '被關注的人數',
  `like_count` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '累計點贊人數',
  `read_count` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '累計閱讀人數',
  PRIMARY KEY (`user_id`),
  UNIQUE KEY `mobile` (`mobile`),
  UNIQUE KEY `user_name` (`user_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='使用者基本資訊表';

CREATE TABLE `user_profile` (
  `user_id` bigint(20) unsigned NOT NULL COMMENT '使用者ID',
  `gender` tinyint(1) NOT NULL DEFAULT '0' COMMENT '性別,0-男,1-女',
  `birthday` date NULL COMMENT '生日',
  `real_name` varchar(32) NULL COMMENT '真實姓名',
  `id_number` varchar(20) NULL COMMENT '身份證號',
  `id_card_front` varchar(128) NULL COMMENT '身份證正面',
  `id_card_back` varchar(128) NULL COMMENT '身份證背面',
  `id_card_handheld` varchar(128) NULL COMMENT '手持身份證',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
  `register_media_time` datetime NULL COMMENT '註冊自媒體時間',
  `area` varchar(20) COMMENT '地區',
  `company` varchar(20) COMMENT '公司',
  `career` varchar(20) COMMENT '職業',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='使用者資料表';

CREATE TABLE `user_relation` (
  `relation_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵id',
  `user_id` bigint(20) unsigned NOT NULL COMMENT '使用者ID',
  `target_user_id` bigint(20) unsigned NOT NULL COMMENT '目標使用者ID',
  `relation` tinyint(1) NOT NULL DEFAULT '0' COMMENT '關係,0-取消,1-關注,2-拉黑',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
  PRIMARY KEY (`relation_id`),
  UNIQUE KEY `user_target` (`user_id`, `target_user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='使用者關係表';

首先需要建立SQLAlchemy物件:

  • 方式一:
db = SQLAlchemy(app)
  • 方式二:
db = SQLAlchemy()
  db.init_app(app)

注意此方式在單獨執行除錯時,對資料庫操作需要在Flask的應用上下文中進行,即

with app.app_context():
      User.query.all()

定義模型類

class User(db.Model):
    """
    使用者基本資訊
    """
    __tablename__ = 'user_basic'

    class STATUS:
        ENABLE = 1
        DISABLE = 0

    id = db.Column('user_id', db.Integer, primary_key=True, doc='使用者ID')
    mobile = db.Column(db.String, doc='手機號')
    password = db.Column(db.String, doc='密碼')
    name = db.Column('user_name', db.String, doc='暱稱')
    profile_photo = db.Column(db.String, doc='頭像')
    last_login = db.Column(db.DateTime, doc='最後登入時間')
    is_media = db.Column(db.Boolean, default=False, doc='是否是自媒體')
    is_verified = db.Column(db.Boolean, default=False, doc='是否實名認證')
    introduction = db.Column(db.String, doc='簡介')
    certificate = db.Column(db.String, doc='認證')
    article_count = db.Column(db.Integer, default=0, doc='發帖數')
    following_count = db.Column(db.Integer, default=0, doc='關注的人數')
    fans_count = db.Column(db.Integer, default=0, doc='被關注的人數(粉絲數)')
    like_count = db.Column(db.Integer, default=0, doc='累計點贊人數')
    read_count = db.Column(db.Integer, default=0, doc='累計閱讀人數')

    account = db.Column(db.String, doc='賬號')
    email = db.Column(db.String, doc='郵箱')
    status = db.Column(db.Integer, default=1, doc='狀態,是否可用')

class UserProfile(db.Model):
    """
    使用者資料表
    """
    __tablename__ = 'user_profile'

    class GENDER:
        MALE = 0
        FEMALE = 1

    id = db.Column('user_id', db.Integer, primary_key=True, doc='使用者ID')
    gender = db.Column(db.Integer, default=0, doc='性別')
    birthday = db.Column(db.Date, doc='生日')
    real_name = db.Column(db.String, doc='真實姓名')
    id_number = db.Column(db.String, doc='身份證號')
    id_card_front = db.Column(db.String, doc='身份證正面')
    id_card_back = db.Column(db.String, doc='身份證背面')
    id_card_handheld = db.Column(db.String, doc='手持身份證')
    ctime = db.Column('create_time', db.DateTime, default=datetime.now, doc='建立時間')
    utime = db.Column('update_time', db.DateTime, default=datetime.now, onupdate=datetime.now, doc='更新時間')
    register_media_time = db.Column(db.DateTime, doc='註冊自媒體時間')

    area = db.Column(db.String, doc='地區')
    company = db.Column(db.String, doc='公司')
    career = db.Column(db.String, doc='職業')


class Relation(db.Model):
    """
    使用者關係表
    """
    __tablename__ = 'user_relation'

    class RELATION:
        DELETE = 0
        FOLLOW = 1
        BLACKLIST = 2

    id = db.Column('relation_id', db.Integer, primary_key=True, doc='主鍵ID')
    user_id = db.Column(db.Integer, doc='使用者ID')
    target_user_id = db.Column(db.Integer, doc='目標使用者ID')
    relation = db.Column(db.Integer, doc='關係')
    ctime = db.Column('create_time', db.DateTime, default=datetime.now, doc='建立時間')
    utime = db.Column('update_time', db.DateTime, default=datetime.now, onupdate=datetime.now, doc='更新時間')

未完待續, 同學們請等待下一期

全套筆記資料程式碼移步: 前往gitee倉庫檢視

感興趣的小夥伴可以自取哦,歡迎大家點贊轉發~

相關文章