flask插件系列之SQLAlchemy實用技巧


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

在多模塊下定義models

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

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

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

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

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,因為不會檢測字段的類型。

辦法:修改字段的名字遷移后再將字段改回遷移,相當於刪除原來的字段重新創建;

  1. 當當前的versions和數據庫的版本不一致導致無法遷移時。

辦法:

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

手動初始化SQLAlchemy

在有些時候,我們沒有初始化APP,但是又想使用models中定義的模型和數據庫的ORM操作,那么就需要手動初始化了。

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對每一個查詢和插入等操作都是一個事務。

  • 解決:在所有的數據庫操作的時候捕捉異常進行事務的回滾。

# 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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM