flask插件系列之SQLAlchemy實用技巧

下面記錄一下SQLAlchemy使用的技巧。python

在多模塊下定義models

  • 若是由多個藍圖下讀定義了model模塊,在初始化的時候須要加載到上下文中。

當使用flask_Migrate遷移數據庫的時候,當執行:mysql

python manage.py db migrate -m '修改說明'

db會默認去上下文中尋找定義的models模型,因此必須在初始化app的時候加載相關models的上下文;所以全部相關的model.py文件都應該在初始化app的時候:sql

from XXX import model

數據遷移的坑

  1. SQLAlchemy當model發生了修改的時候,其是不能識別字段的的類型和字段大小的。
from extensions import db

class User(db.model)
    __tablename__ = 'users'
    user_id = db.Column(db.String(8), primary_key=True) 

# 改成
class User(db.model)
    __tablename__ = 'users'
    user_id = db.Column(db.String(20), primary_key=True)

問題:直接遷移會出現no change,由於不會檢測字段的類型。數據庫

辦法:修改字段的名字遷移後再將字段改回遷移,至關於刪除原來的字段從新建立;flask

  1. 噹噹前的versions和數據庫的版本不一致致使沒法遷移時。

辦法:session

# 刪除原來的migrations文件夾;
# 去數據庫刪除alembic_version表的內容;
# 從新執行數據庫遷移操做;

手動初始化SQLAlchemy

在有些時候,咱們沒有初始化APP,可是又想使用models中定義的模型和數據庫的ORM操做,那麼就須要手動初始化了。app

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from models import AdminUser

# 建立一個配置對象
engine = create_engine('mysql+pymysql://username:passwd@ip:port/db?charset=utf8', convert_unicode=True)
# 建立一個會話
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))
# 初始化查詢對象
AdminUser.query = db_session.query_property()

# 下面就跟在框架中同樣了
admin = AdminUser()
admin.id = 1
admin.username = username
admin.password = pwd
db_session.add(admin)
db_session.commit()

查詢報錯:sqlalchemy.exc.InvalidRequestError: Can't reconnect until invalid transaction is rolled back

  • 緣由是:鏈接斷開後,事務沒有回滾,殘留的鎖致使後續的查詢報錯.sqlalchemy對每個查詢和插入等操做都是一個事務。框架

  • 解決:在全部的數據庫操做的時候捕捉異常進行事務的回滾。code

# main.py
from models import OrderInfo 
from sqlalchemy.exc import InvalidRequestError
try:
    order = OrderInfo.query.filter_by(task_id=user_dict.get('task_id')).first()
    order.status = 'COMPLETE'
    db.session.commit()
except InvalidRequestError:
    db.session.rollback()
except Exception as e:
    print(e)
相關文章
相關標籤/搜索