1. 程式人生 > 實用技巧 >詳細解析Java記憶體,編輯器,編譯器重排序以及它對執行緒的影響

詳細解析Java記憶體,編輯器,編譯器重排序以及它對執行緒的影響

SQLALchemy 實際上是對資料庫的抽象,讓開發者不用直接和 SQL 語句打交道,而是通過 Python 物件來操作資料庫,在捨棄一些效能開銷的同時,換來的是開發效率的較大提升

SQLAlchemy是一個關係型資料庫框架,它提供了高層的 ORM 和底層的原生資料庫的操作。

flask-sqlalchemy 是一個簡化了 SQLAlchemy 操作的flask擴充套件。

文件地址:http://docs.jinkan.org/docs/flask-sqlalchemy

安裝

安裝 flask-sqlalchemy
pip install flask-sqlalchemy
如果連線的是 mysql 資料庫,需要安裝 mysqldb
pip install flask
-mysqldb 資料庫連線設定 在 Flask-SQLAlchemy 中,資料庫使用URL指定,而且程式使用的資料庫必須儲存到Flask配置物件的 SQLALCHEMY_DATABASE_URI 鍵中 app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:[email protected]:3306/test' 其他設定: # 動態追蹤修改設定,如未設定只會提示警告 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True #查詢時會顯示原始SQL語句 app.config['SQLALCHEMY_ECHO'
] = True 配置完成需要去 MySQL 中建立專案所使用的資料庫 $ mysql -uroot -pmysql $ create database test charset utf8;

其它配製

名字                             備註
SQLALCHEMY_DATABASE_URI         用於連線的資料庫 URI 。例如:sqlite:////tmp/test.dbmysql://username:password@server/db
SQLALCHEMY_ECHO             如果設定為Ture, SQLAlchemy 會記錄所有 發給 stderr 的語句,這對除錯有用。(列印sql語句)
SQLALCHEMY_RECORD_QUERIES        可以用於顯式地禁用或啟用查詢記錄。查詢記錄 在除錯或測試模式自動啟用。更多資訊見get_debug_queries()。
SQLALCHEMY_POOL_SIZE             資料庫連線池的大小。預設是引擎預設值(通常 是 
5 ) SQLALCHEMY_POOL_TIMEOUT 設定連線池的連線超時時間。預設是 10 。 SQLALCHEMY_COMMIT_ON_TEARDOWN 資料庫內容傳送改變之後,自動提交

常用的SQLAlchemy欄位型別

常用的SQLAlchemy列選項

常用的SQLAlchemy關係選項

資料庫基本操作

在Flask-SQLAlchemy中,插入、修改、刪除操作,均由資料庫會話管理。

會話用 db.session 表示。在準備把資料寫入資料庫前,要先將資料新增到會話中然後呼叫 commit() 方法提交會話。

在 Flask-SQLAlchemy 中,查詢操作是通過 query 物件操作資料。最基本的查詢是返回表中所有資料,可以通過過濾器進行更精確的資料庫查詢。

在檢視函式中定義模型類

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

#設定連線資料庫的URL
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:[email protected]:3306/test'

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
#查詢時會顯示原始SQL語句
app.config['SQLALCHEMY_ECHO'] = True
db = SQLAlchemy(app)

class Role(db.Model):
    # 定義表名
    __tablename__ = 'roles'
    # 定義列物件
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    us = db.relationship('User', backref='role')

    #repr()方法顯示一個可讀字串
    def __repr__(self):
        return 'Role:%s'% self.name

class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True, index=True)
    email = db.Column(db.String(64),unique=True)
    password = db.Column(db.String(64))
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))

    def __repr__(self):
        return 'User:%s'%self.name
if __name__ == '__main__':
    app.run(debug=True)
View Code

CRDB(增刪改查)

#建立表:
db.create_all()
#刪除表
db.drop_all()
#插入一條資料
ro1 = Role(name='admin')
db.session.add(ro1)
db.session.commit()
#再次插入一條資料
ro2 = Role(name='user')
db.session.add(ro2)
db.session.commit()
#插入多條記錄
us1 = User(name='wang',email='[email protected]',password='123456',role_id=ro1.id)
us2 = User(name='zhang',email='[email protected]',password='201512',role_id=ro2.id)
db.session.add_all([us1,us2])
db.session.commit()
View Code

查詢

常用的SQLAlchemy查詢過濾器

常用的SQLAlchemy查詢執行器

user = User.query.first()
user.name = 'dong'
db.session.commit()
User.query.first()
View Code

#filter_by精確查詢
#返回名字等於wang的所有人
User.query.filter_by(name='wang').all()
#過濾名字
#first()返回查詢到的第一個物件
User.query.first()
#all()返回查詢到的所有物件
User.query.all()
#查詢所有物件
#filter模糊查詢,返回名字結尾字元為g的所有資料。
User.query.filter(User.name.endswith('g')).all()
#模糊查詢
#get():引數為主鍵,如果主鍵不存在沒有返回內容
User.query.get()
#邏輯非,返回名字不等於wang的所有資料
User.query.filter(User.name!='wang').all()
#邏輯非
#not_ 相當於取反
from sqlalchemy import not_
User.query.filter(not_(User.name=='chen')).all()
#取反
#邏輯與,需要匯入and,返回and()條件滿足的所有資料
from sqlalchemy import and_
User.query.filter(and_(User.name!='wang',User.email.endswith('163.com'))).all()
#邏輯與
#邏輯或,需要匯入or_
from sqlalchemy import or_
User.query.filter(or_(User.name!='wang',User.email.endswith('163.com'))).all()
View Code

刪除

user = User.query.first()
db.session.delete(user)
db.session.commit()
User.query.all()
View Code

更新資料

模型之前的關聯

一對多

class Role(db.Model):
    ...
    #關鍵程式碼
    us = db.relationship('User', backref='role', lazy='dynamic')
    ...

class User(db.Model):
    ...
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
View Code

其中realtionship描述了Role和User的關係。在此文中,第一個引數為對應參照的類"User"

第二個引數backref為類User申明新屬性的方法

第三個引數lazy決定了什麼時候SQLALchemy從資料庫中載入資料

如果設定為子查詢方式(subquery),則會在載入完Role物件後,就立即載入與其關聯的物件,這樣會讓總查詢數量減少,但如果返回的條目數量很多,就會比較慢

設定為 subquery 的話,role.users 返回所有資料列表

另外,也可以設定為動態方式(dynamic),這樣關聯物件會在被使用的時候再進行載入,並且在返回前進行過濾,如果返回的物件數很多,或者未來會變得很多,那最好採用這種方式

設定為 dynamic 的話,role.users 返回查詢物件,並沒有做真正的查詢,可以利用查詢物件做其他邏輯,比如:先排序再返回結果

關聯查詢示例:

角色和使用者的關係是一對多的關係,一個角色可以有多個使用者,一個使用者只能屬於一個角色。

#查詢角色的所有使用者
#查詢roles表id為1的角色
ro1 = Role.query.get(1)
#查詢該角色的所有使用者
ro1.us.all()


#查詢使用者所屬角色
#查詢users表id為3的使用者
us1 = User.query.get(3)
#查詢使用者屬於什麼角色
us1.role
View Code

多對多

registrations = db.Table('registrations',  
    db.Column('student_id', db.Integer, db.ForeignKey('students.id')),  
    db.Column('course_id', db.Integer, db.ForeignKey('courses.id'))  
)  
class Course(db.Model):
    ...
class Student(db.Model):
    ...
    courses = db.relationship('Course',secondary=registrations,  
                                    backref='students',  
                                    lazy='dynamic')
View Code