Go(又稱為Golang)是一門由Google開發的開源編程語言,於2009年首次公開發佈。Go語言被設計用來提高軟體開發的效率和可靠性,在處理大規模系統時表現出色。以下是Go語言的一些特點和優勢: 特點 簡潔易讀:Go語法簡潔清晰,易於閱讀和學習,減少了代碼的複雜性。 併發支持:Go原生支持輕量級 ...
嘿馬頭條項目從到完整開發筆記總結完整教程(附代碼資料)主要內容講述:課程簡介,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
作用
-
省去自己拼寫SQL,保證SQL語法的正確性
-
一次編寫可以適配多個資料庫
-
防止註入
-
在資料庫表名或欄位名發生變化時,只需修改模型類的映射,無需修改資料庫操作的代碼
(相比SQL的話,可能需要同步修改涉及到的每一個SQL語句)
思考:
可否在已經存在資料庫表的情況下,使用模型類進行操作?
使用ORM的方式選擇
-
先創建模型類,再遷移到資料庫中
- 優點:簡單快捷,定義一次模型類即可,不用寫sql
- 缺點:不能盡善盡美的控制創建表的所有細節問題,表結構發生變化的時候,也會難免發生遷移錯誤
-
先用原生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:[email protected]: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:[email protected]: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='更新時間')