1. 程式人生 > 其它 >DAY5 MySQL資料庫專案想關表的建立和匯入測試資料和表的講解

DAY5 MySQL資料庫專案想關表的建立和匯入測試資料和表的講解

資料庫表的建立

完成主頁的渲染之後,我們就要處理我麼後臺的MySQL資料庫了,這個專案的所有表的建立使用了我們flask框架中ORM(物件關係對映),既通過建立模型類的形式來建立我們

所需要的資料表來儲存我們需要儲存的資料以及相關表間關係的處理。

在專案中所有表的模型類是單獨存放在一個檔案裡面的,我們在專案的info資料夾下建一個新的檔案models,裡面存放我們這次專案所需的所有模型類。

from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash

from info import constants
from . import db


class BaseModel(object):
    """模型基類,為每個模型補充建立時間與更新時間"""
    create_time = db.Column(db.DateTime, default=datetime.now)  # 記錄的建立時間
    update_time = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)  # 記錄的更新時間


# 使用者收藏表,建立使用者與其收藏新聞多對多的關係
tb_user_collection = db.Table(
    "info_user_collection",
    db.Column("user_id", db.Integer, db.ForeignKey("info_user.id"), primary_key=True),  # 新聞編號
    db.Column("news_id", db.Integer, db.ForeignKey("info_news.id"), primary_key=True),  # 分類編號
    db.Column("create_time", db.DateTime, default=datetime.now)  # 收藏建立時間
)

tb_user_follows = db.Table(
    "info_user_fans",
    db.Column('follower_id', db.Integer, db.ForeignKey('info_user.id'), primary_key=True),  # 粉絲id
    db.Column('followed_id', db.Integer, db.ForeignKey('info_user.id'), primary_key=True)  # 被關注人的id
)


class User(BaseModel, db.Model):
    """使用者"""
    __tablename__ = "info_user"

    id = db.Column(db.Integer, primary_key=True)  # 使用者編號
    nick_name = db.Column(db.String(32), unique=True, nullable=False)  # 使用者暱稱
    password_hash = db.Column(db.String(128), nullable=False)  # 加密的密碼
    mobile = db.Column(db.String(11), unique=True, nullable=False)  # 手機號
    avatar_url = db.Column(db.String(256))  # 使用者頭像路徑
    last_login = db.Column(db.DateTime, default=datetime.now)  # 最後一次登入時間
    is_admin = db.Column(db.Boolean, default=False)
    signature = db.Column(db.String(512))  # 使用者簽名
    gender = db.Column(  # 訂單的狀態
        db.Enum(
            "MAN",  # 男
            "WOMAN"  # 女
        ),
        default="MAN")

    # 當前使用者收藏的所有新聞
    collection_news = db.relationship("News", secondary=tb_user_collection, lazy="dynamic")  # 使用者收藏的新聞
    # 使用者所有的粉絲,添加了反向引用followed,代表使用者都關注了哪些人
    followers = db.relationship('User',
                                secondary=tb_user_follows,
                                primaryjoin=id == tb_user_follows.c.followed_id,
                                secondaryjoin=id == tb_user_follows.c.follower_id,
                                backref=db.backref('followed', lazy='dynamic'),
                                lazy='dynamic')

    # 當前使用者所釋出的新聞
    news_list = db.relationship('News', backref='user', lazy='dynamic')

    def to_dict(self):
        resp_dict = {
            "id": self.id,
            "nick_name": self.nick_name,
            "avatar_url": constants.QINIU_DOMIN_PREFIX + self.avatar_url if self.avatar_url else "",
            "mobile": self.mobile,
            "gender": self.gender if self.gender else "MAN",
            "signature": self.signature if self.signature else "",
            "followers_count": self.followers.count(),
            "news_count": self.news_list.count()
        }
        return resp_dict

    def to_admin_dict(self):
        resp_dict = {
            "id": self.id,
            "nick_name": self.nick_name,
            "mobile": self.mobile,
            "register": self.create_time.strftime("%Y-%m-%d %H:%M:%S"),
            "last_login": self.last_login.strftime("%Y-%m-%d %H:%M:%S"),
        }
        return resp_dict


class News(BaseModel, db.Model):
    """新聞"""
    __tablename__ = "info_news"

    id = db.Column(db.Integer, primary_key=True)  # 新聞編號
    title = db.Column(db.String(256), nullable=False)  # 新聞標題
    source = db.Column(db.String(64), nullable=False)  # 新聞來源
    digest = db.Column(db.String(512), nullable=False)  # 新聞摘要
    content = db.Column(db.Text, nullable=False)  # 新聞內容
    clicks = db.Column(db.Integer, default=0)  # 瀏覽量
    index_image_url = db.Column(db.String(256))  # 新聞列表圖片路徑
    category_id = db.Column(db.Integer, db.ForeignKey("info_category.id"))
    user_id = db.Column(db.Integer, db.ForeignKey("info_user.id"))  # 當前新聞的作者id
    status = db.Column(db.Integer, default=0)  # 當前新聞狀態 如果為0代表稽核通過,1代表稽核中,-1代表稽核不通過
    reason = db.Column(db.String(256))  # 未通過原因,status = -1 的時候使用
    # 當前新聞的所有評論
    comments = db.relationship("Comment", lazy="dynamic")

    def to_review_dict(self):
        resp_dict = {
            "id": self.id,
            "title": self.title,
            "create_time": self.create_time.strftime("%Y-%m-%d %H:%M:%S"),
            "status": self.status,
            "reason": self.reason if self.reason else ""
        }
        return resp_dict

    def to_basic_dict(self):
        resp_dict = {
            "id": self.id,
            "title": self.title,
            "source": self.source,
            "digest": self.digest,
            "create_time": self.create_time.strftime("%Y-%m-%d %H:%M:%S"),
            "index_image_url": self.index_image_url,
            "clicks": self.clicks,
        }
        return resp_dict

    def to_dict(self):
        resp_dict = {
            "id": self.id,
            "title": self.title,
            "source": self.source,
            "digest": self.digest,
            "create_time": self.create_time.strftime("%Y-%m-%d %H:%M:%S"),
            "content": self.content,
            "comments_count": self.comments.count(),
            "clicks": self.clicks,
            "category": self.category.to_dict(),
            "index_image_url": self.index_image_url,
            "author": self.user.to_dict() if self.user else None
        }
        return resp_dict


class Comment(BaseModel, db.Model):
    """評論"""
    __tablename__ = "info_comment"

    id = db.Column(db.Integer, primary_key=True)  # 評論編號
    user_id = db.Column(db.Integer, db.ForeignKey("info_user.id"), nullable=False)  # 使用者id
    news_id = db.Column(db.Integer, db.ForeignKey("info_news.id"), nullable=False)  # 新聞id
    content = db.Column(db.Text, nullable=False)  # 評論內容
    parent_id = db.Column(db.Integer, db.ForeignKey("info_comment.id"))  # 父評論id
    parent = db.relationship("Comment", remote_side=[id])  # 自關聯
    like_count = db.Column(db.Integer, default=0)  # 點贊條數

    def to_dict(self):
        resp_dict = {
            "id": self.id,
            "create_time": self.create_time.strftime("%Y-%m-%d %H:%M:%S"),
            "content": self.content,
            "parent": self.parent.to_dict() if self.parent else None,
            "user": User.query.get(self.user_id).to_dict(),
            "news_id": self.news_id,
            "like_count": self.like_count
        }
        return resp_dict


class CommentLike(BaseModel, db.Model):
    """評論點贊"""
    __tablename__ = "info_comment_like"
    comment_id = db.Column("comment_id", db.Integer, db.ForeignKey("info_comment.id"), primary_key=True)  # 評論編號
    user_id = db.Column("user_id", db.Integer, db.ForeignKey("info_user.id"), primary_key=True)  # 使用者編號


class Category(BaseModel, db.Model):
    """新聞分類"""
    __tablename__ = "info_category"

    id = db.Column(db.Integer, primary_key=True)  # 分類編號
    name = db.Column(db.String(64), nullable=False)  # 分類名
    news_list = db.relationship('News', backref='category', lazy='dynamic')

    def to_dict(self):
        resp_dict = {
            "id": self.id,
            "name": self.name
        }
        return resp_dict

下一步我們將使用這個檔案生成我們在MySQL資料庫中存放資料的表:

 首先我們需要將我們的models檔案匯入到主檔案中執行:

因為這裡我是隻是單獨的讓檔案執行不是使用,所以是灰色的,沒有關係,下一步輸入指令碼命令

因為我們之前已經連線好了資料庫並進行資料庫遷移資料夾的生成:

所以我們這次要建立所有的表並生成最初始版本記錄:

在pycharm自帶的命令控制檯輸入

指令碼程式碼為:

python manage.py mysql migrate -m"init"(-m後面的內容為本次生成版本的註釋,init為初始化

INFO 的內容為我們所建立的表的名字,done表示已經生成了最開始的版本號,現在開啟我們的遷移資料夾會發現有一個新的

檔案,裡面就是本次我們所執行的內容,但是資料庫裡面還是沒有建立我們所有的表,我們需要將資料庫更新到本次版本,

使用下面的指令碼程式碼:

python manage.py mysql upgrade (升版本)


執行後我們的資料庫就建立好了,通過pycharm的視覺化資料庫就可以檢視我們所有的資料表:

第一個為我們的版本表,裡面是我們每次操作表的版本號。

下面我們在表裡存放測試資料來測試一下是否存在亂碼問題。

開啟我們的MySQL提示符進入到專案資料庫並進行檢視:

下面我們插入我們的測試資料,我們將以資料檔案的形式來進行操作

這裡我們插入的表是新聞的標題表以及存放新聞的新聞表,它們之間存在著一對多的關係,所以在多的一方有著多的一方外來鍵的資料,也就是ID,所以

要先插入標題表的資料再插入新聞表

source 命令程式碼 然後再將插入的資料檔案直接用滑鼠拖到後面,會自動補全檔案的絕對路徑,儲存的時候儘量不要在路徑中出現中文

 

然後再是新聞:

然後在我們的pycharm的視覺化資料庫中進行插入資料的檢視,看是否有亂碼:

OK,沒有亂碼,我們的專案的所有表的建立和執行就沒有問題了,下一步我們做一個簡單的表間關係的分析,以及表的建立數量和表的名字

表的分析

一個專案所需那些表需要我們自己通過專案前端頁面,也就是前端所需的所有資料來進行分析,這是一個從無到有的過程,

需要我們仔細的分析,有可能初次考慮的不全,後面慢慢補全就行,

開啟我們專案的前端頁面: 

 這裡我簡單的分析一下,後面會有詳細 的關係圖,這裡只是我自己的分析:

首先有存放新聞的表 ,然後是存放新聞分類的表,它們之間的一對多的關係,一是分類,多是新聞,所以新聞應該有

分類ID的外來鍵存在,這樣這兩張表的關係就完成了,點選排行也是新聞,所以不需要單獨的表,新聞表就可以存

然後是使用者資料表,,這就是最基礎的三張表,如下圖還剩下4張表,我簡單的分析一下吧:

User_Fans:使用者和使用者之間還存在著關注和被關注的關係,這是一個多對多關係,既一個人能被多個人關注,也能關注多個人。所以有User_Fans表來維持它們之間的關係

裡面也就只需要存放使用者的相關使用者的id即可.

User_Collection:使用者和新聞之間的第三表,使用者收藏新聞以及新聞被使用者收藏,多對多。(其實使用者也可以寫新聞,所以還存在著一對多,所以新聞裡user_id也是一個外來鍵。) 

Comment:新聞評論表,一個新聞可以有多條新聞,但是每個新聞的評論區是不同的,所以是一對多的關係。所以存放評論的評論表裡有新聞的ID這個外來鍵,使用者來進行評論所以也有使用者的ID外來鍵

comment_like:使用者點贊表,評論相關的表的分析我還暫時沒有懂,後續懂了之後再做分析吧。現在先簡單的分析到這。