SQLAlchemy與Flask-SQLAlchemy

在web應用里使用原生的SQL語句操作數(shù)據(jù)庫主要存在下面兩類問題:

1.手動編寫SQL語句比較乏味,而且視圖函數(shù)中加入太多的SQL語句會降低代碼的易讀性。另外還容易出現(xiàn)安全問題,比如SQL注入。
2.在部署時切換到不通的DBMS,我們需要使用不同的Python接口庫,這讓DBMS的切換變的不太容易。

下面利用SQLAlchemy對MySQL進行簡單的CRUD操作
# -*- coding: utf-8 -*-
"""利用sqlalchemy對mysql進行簡單的增刪改查"""

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Column, Integer, String, DateTime, Boolean

engine = create_engine('mysql+pymysql://root:root@localhost:3306/news?charset=utf8')  # 連接news數(shù)據(jù)庫(news庫需提前創(chuàng)建好)
Session = sessionmaker(bind=engine)
Base = declarative_base()


class News(Base):
    """
    在python終端執(zhí)行以下命令手動創(chuàng)建表
    from sqlalchemy_test import News, engine
    News.metadata.create_all(engine)
    """
    # 表名
    __tablename__ = 'news'
    id = Column(Integer, primary_key=True, autoincrement=True)
    title = Column(String(200), nullable=False)
    content = Column(String(2000), nullable=False, default='新聞內(nèi)容')
    types = Column(String(20), nullable=False)
    image = Column(String(300), default="")
    author = Column(String(20), default="")
    view_count = Column(Integer, default=0)
    created_at = Column(DateTime)
    is_valid = Column(Boolean, default=True)


class MysqlOrmTest(object):
    def __init__(self):
        self.session = Session()

    def add_one(self):
        # 添加一條數(shù)據(jù)
        news_obj = News(
            title='標題',
            types='體育',
            content="新聞內(nèi)容"
        )
        self.session.add(news_obj)
        self.session.commit()
        return news_obj

    def add_more(self):
        """添加多條數(shù)據(jù)"""
        self.session.add_all([
            News(title='標題2', types='推薦', content="新聞內(nèi)容"),
            News(title='標題3', types='百家', content="新聞內(nèi)容"),
            News(title='標題4', types='軍事', content="新聞內(nèi)容"),
            News(title='標題5', types='推薦', content="新聞內(nèi)容")
        ])
        self.session.commit()

    def get_more(self):
        """獲取多條數(shù)據(jù)"""
        return self.session.query(News).filter_by(is_valid=1)

    def get_one(self):
        """獲取一條數(shù)據(jù)"""
        return self.session.query(News).get(8)   # 獲取id為8的數(shù)據(jù)

    def update_data(self):
        """"數(shù)據(jù)更新 """
        obj = self.session.query(News).get(4)
        obj.is_valid = 0
        self.session.add(obj)
        self.session.commit()
        return obj.is_valid

    def delete_data(self):
        """刪除數(shù)據(jù)"""
        # 獲取要刪除的數(shù)據(jù)
        data = self.session.query(News).get(8)
        self.session.delete(data)
        self.session.commit()


def main():
    obj = MysqlOrmTest()
    # 增加一條數(shù)據(jù)
    result = obj.add_one()
    # 增加多條數(shù)據(jù)
    obj.add_more()
    # 獲取一條數(shù)據(jù)
    result = obj.get_one()
    # 獲取多條數(shù)據(jù)
    result = obj.get_more()
    for item in result:
        print(item.title)
    print(obj.update_data())
    # 刪除數(shù)據(jù)
    obj.delete_data()


if __name__ == "__main__":
    main()
Flask-SQLAlchemy是對SQLAlchemy又進行了一層封裝
# -*- coding: utf-8 -*-
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:root@localhost:3306/note?charset=utf8'
db = SQLAlchemy(app)
class Note(db.Model):
    """
     在python終端執(zhí)行以下命令手動創(chuàng)建表
     from flask_sqlalchemy_test import db
     db.create_all()
    """
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    body = db.Column(db.Text)

    def __repr__(self):
        return '<Note %r>' % self.body
Create
note1 = Note(body="這是第1條筆記")
note2 = Note(body="這是第2條筆記")
db.session.add(note1)
db.session.add(note2)
db.session.commit()

除了依次調(diào)用add()方法添加多個記錄,也可以使用add_all()一次添加包含所有記錄對象的列表

Read

一般來說,一個完整的查詢遵循<模型類名>.query.<過濾方法>.<查詢方法>的模式
all(): 返回所有的記錄

Note.query.all()

first(): 返回第一條記錄

note1 = Note.query.first() 
print(note1.id)

count(): 返回記錄的數(shù)量

Note.query.count()

get(): 指定主鍵值(id字段)的記錄

note2 = Note.query.get(2)   # 讀取表中id為2的數(shù)據(jù)
print(note2.body)

filter(): 它使用指定的規(guī)則來過濾記錄

Note.query.filter(Note.body=='SHAVE').first()    #找出body字段值為SHAVE的記錄

LIKE

filter(Note.body.like('%foo%'))

IN

filter(Note.body.in_(['foo','bar','baz']))

NOT IN

filter(~Note.body.in_(['foo','bar','baz']))

AND
1.使用and_()

from sqlalchemy import and_
filter(and_(Note.body == 'foo',Note.title == 'foobar'))

2.或在filter()中加入多個表達式,使用逗號分隔

filter(Note.body == 'foo', Note.title == 'foobar')

3.或疊加調(diào)用多個filter() / filter_by()方法

filter(Note.body == 'foo').filter(Note.title == 'foobar')

OR 使用or_()

from sqlalchemy import or_
filter(or_(Note.body == 'foo', Note.body == 'bar'))

filter_by():在filter_by方法中,你可以使用關鍵字表達式來指定過濾規(guī)則。

Note.query.filter(body=='SHAVE').first()

更多的查詢方法和過濾方法可參考(http://docs.sqlalchemy.org/en/lates/orm/query.html)

Update

更新一條記錄非常簡單,直接賦值給模型類的字段屬性就可以改變字段值,然后調(diào)用commit()方法提交會話即可。

note = Note.query.get(3)
note.body = "hello world"
db.session.commit()

只有要插入新的記錄或將現(xiàn)有的記錄添加到會話中時才需要add()方法,單純要更新現(xiàn)有的記錄時只需要直接為屬性賦值,然后提交會話。

Delete
note = Note.query.get(2)
db.session.delete(note)
db.session.commit()

刪除記錄和添加記錄很相似,最后都需調(diào)用commit()方法提交需改

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容