SQLAlchemy的官網上寫着它的介紹文字: html
SQLAlchemy is the Python SQL toolkit and Object Relational Mapper that gives application developers the full power and flexibility of SQL.SQLAlchemy 是一個很是強大的ORM和數據庫工具,可是它龐大的文檔和複雜的功能老是讓很 多人望而生畏。
接下來羅列SQLAlchemy針對平常的數據庫操做 python
文中使用的 SQLAlchemy 版本爲 0.9.8 mysql
創建數據表 sql
from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String, ForeignKey, Date from sqlalchemy.orm import relationship, backref Base = declarative_base() # 定義表結構 class GameCompany(Base): __tablename__ = 'game_company' id = Column(Integer, primary_key=True) name = Column(String(200), nullable=False) country = Column(String(50)) class Game(Base): __tablename__ = 'game' id = Column(Integer, primary_key=True) company_id = Column(Integer, ForeignKey('game_company.id'), index=True) category = Column(String(10)) name = Column(String(200), nullable=False) release_date = Column(Date) # 和Django不一樣,外鍵須要顯式定義,具體好壞見仁見智 # 此處的relation能夠爲lazy加載外鍵內容時提供一些可配置的選項 company = relationship('GameCompany', backref=backref('games')) # 此處定義要使用的數據庫 engine = create_engine('mysql://root:root@localhost:5379/sqlalchemy_tutorial?charset=utf8') # 調用create_all來建立表結構,已經存在的表將被忽略 Base.metadata.create_all(engine)
接下來,咱們往表中插入一些數據 數據庫
在SQLAlchemy ORM中,有一個很是關鍵的對象 session ,全部對於數據的操做都是 經過session來進行的,因此要插入數據以前,咱們得先初始化一個session:from sqlalchemy.orm import sessionmaker Session = sessionmaker(bind=engine) session = Session()
插入數據 session
# 添加數據 nintendo = GameCompany(name="Nintendo", country="Japan") capcom = GameCompany(name="Capcom", country="Japan") game1 = Game( company=nintendo, category="ACT", name="Super Mario Bros", release_date='1985-10-18' ) game2 = Game( company=capcom, category="ACT", name="Devil May Cry 3: Dante's Awakening", release_date="2005-03-01", ) game3 = Game( company=nintendo, category="RPG", name="Mario & Luigi: Dream Team", release_date="2013-08-11", ) # 使用add_all來讓這些objects和session產生關係 session.add_all([nintendo, capcom, game1, game2]) # 在沒有開啓autocommit的模式下,不要忘了調用commit來讓數據寫到數據庫中 session.commit()
除了commit以外,session還有rollback()等方法,你能夠把session對象簡單當作是一次 transaction,因此當你對內容進行修改時,須要調用 session.commit() 來提交這些修改。 app
去文檔能夠了解更多session相關內容:http://docs.sqlalchemy.org/en/rel_0_9/orm/session.html 工具
批量查詢 flex
session.query(Game).filter_by(category="RPG") session.query(Game).filter(Game.category == "RPG")
查詢單個對象 ui
session.query(Game).filter_by(name="Super Mario Bros").one() # `get_objects_or_None()` session.query(Game).filter_by(name="Super Mario Bros").scalar()
運算符重載
session.query(Game).filter(Game.release_date >= '1999-01-01').count() # 取反使用 ~ 運算符 session.query(Game).filter(~Game.release_date >= '1999-01-01').count()
session.query(Game).join(GameCompany).filter(GameCompany.name == "Nintendo")
多條件或查詢
from sqlalchemy import or_ session.query(Game).filter(or_(Game.category == "RPG", Game.category == "ACT")) session.query(Game).filter((Game.category == "RPG") | (Game.category == "ACT"))
session.query(Game).filter(Game.category.in_(["GAL", "ACT"]))
like查詢
session.query(Game.name.contains('Mario'))
簡單統計總數
session.query(Game).filter_by(category="RPG").count()
分組統計個數
from sqlalchemy import func session.query(Game.category, func.count(Game.category)).group_by(Game.category).all()
結果排序
對查詢結果進行排序
session.query(Game).order_by(Game.release_date) session.query(Game).order_by(Game.release_date.desc()) # 多字段排序 session.query(Game).order_by(Game.release_date.desc(), Game.category)
game = session.query(Game).get(1) game.name = 'Super Mario Brothers' session.commit()
session.query(Game).filter_by(category="RPG").update({"category": "ARPG"})
session.query(Game).filter_by(category="ARPG").delete()
上面簡單列了一些SQLAlchemy ORM的使用方法,SQLAlchemy同時還提供了一些 其餘很是有用的功能。
假如你有一個Django項目,經過ORM建立了一大堆Model。這時來了一個新項目,須要操做 這些表,應該怎麼辦?拷貝這些Models?使用原始的DB-API加上sql來操做?
其實使用SQLAlchemy的Automap可讓你的工做變得很是的方便,你只要在新項目鏈接到舊數據庫,而後 稍微配置一下Automap,就可使用SQLAlchemy的ORM操做那些經過別的系統建立的表了。
就像這樣:
from sqlalchemy.ext.automap import automap_base from sqlalchemy.orm import Session from sqlalchemy import create_engine Base = automap_base() engine = create_engine("sqlite:///mydatabase.db") Base.prepare(engine, reflect=True) # user和address就是代表,經過這樣的語句就能夠把他們分別映射到User和Address類 User = Base.classes.user Address = Base.classes.address
更多信息能夠參考詳細文檔:http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/automap.html
Django有south能夠方便作表結構修改?SQLAlchemy固然也能夠,甚至比south更爲強大。 自動migrate?手動migrate?通通不是問題。
更多信息可參考文檔:http://alembic.readthedocs.org/en/latest/index.html