ORM
是Object-Relational Mapping的簡寫。今天學習的SQLAlchemy
其實就是ORM框架中最有名的一個。SQLAlchemy
框架工做pymysql
等第三方插件。上圖中Dialect用於和數據API進行交流,根據配置文件的不一樣調用不一樣的數據庫API,從而實現對數據庫的操做。
1 2 3 4 5 6 7 8 |
# mysqldb mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname> # pymysql mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>] # mysql-connector mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname> # cx_oracle oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...] |
ORM思想的核心是隱藏了數據訪問細節,提供了通用的數據庫交互。而且徹底不用考慮SQL語句,從而快速開發。html
1 2 3 4 5 6 7 |
CREATE TABLE student( id int not null auto_increment, name varchar(100), age int, address varchar(100), PRIMARY KEY(id) ) |
上述是一個簡單的建立單表的語句。python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
from sqlalchemy import create_engine, Column, String, Integer, MetaData from sqlalchemy.ext.declarative import declarative_base engine = create_engine("mysql+pymysql://root:123456@localhost/test", encoding='UTF-8', echo=True) Base = declarative_base() #生成orm基類 class Student(Base): __tablename__ = 'student' #指定表名 id = Column(Integer, primary_key=True) name = Column(String(100)) age = Column(Integer) address = Column(String(100)) Base.metadata.create_all(engine) #建立表結構 |
方法2mysql
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
from sqlalchemy import Table, MetaData, Column, Integer, String, create_engine from sqlalchemy.orm import mapper engine = create_engine("mysql+pymysql://root:123456@localhost/test", encoding='UTF-8', echo=True) metadata = MetaData() student = Table('student', metadata, Column('id', Integer, primary_key=True), Column('name', String(100)), Column('age', Integer), Column('address', String(100)) ) class Student(object): def __init__(self, name, age, address): self.name = name self.age = age self.address = address mapper(Student, student) #此處有問題,待解決 |
說明
echo=True
顯示每條執行的SQL語句,能夠關閉。
create_engine()
返回一個Engine的實例,而且表示經過數據庫語法處理細節的核心接口,這種狀況下數據庫語法將被解釋成python的類方法。
上面簡單示例對比了下使用SQL直接建立表和使用ORM框架建表的區別,下面開始介紹SQLAlchemy
的使用。sql
經過pip install SQLAlchemy
安裝,訪問mysql使用pymysql
,安裝方法pip install pumysql
。能夠參照python訪問mysql。數據庫
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
from sqlalchemy import create_engine, Column, String, Integer, MetaData from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker engine = create_engine("mysql+pymysql://root:123456@localhost/test", encoding='UTF-8', echo=True) DBsession = sessionmaker(bind=engine) #建立與數據庫的會話session class ,注意,這裏返回給session的是個class,不是實例 session = DBsession() #生成session實例 Base = declarative_base() class Student(Base): __tablename__ = 'student' id = Column(Integer, primary_key=True) name = Column(String(100)) age = Column(Integer) address = Column(String(100)) student1 = Student(id=1001, name='Alice', age=25, address="anhui") student2 = Student(id=1002, name='Bob', age=69, address="beijing") student3 = Student(id=1003, name='Cerry', age=14, address="jiangsu") session.add_all([student1, student2, student3]) session.commit() session.close() |
查詢是經過Session的query()
方法建立一個查詢對象,這個函數的參數能夠是任何類或者類的描述的集合。
查詢出來的數據是一個對象,直接經過對象的屬性調用。數組
1 2 3 4 5 6 7 8 9 10 11 12 |
from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from db.orm2 import Student engine = create_engine('mysql+pymysql://root:123456@localhost/test') DBsession = sessionmaker(bind=engine) session = DBsession() a = session.query(Student) print(a) for i in a: print(i.id, i.name, i.age, i.address) |
輸出結果session
1 2 3 4 5 |
SELECT student.id AS student_id, student.name AS student_name, student.age AS student_age, student.address AS student_address FROM student 1001 Alice 25 anhui 1002 Bob 69 beijing 1003 Cerry 14 jiangsu |
session.query(Student)
結果爲查詢的SQL語句,若出現查詢結果錯誤能夠經過查看SQL確認。oracle
==
、!=
、like
等過濾操做均可以在filter函數中使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from db.orm2 import Student engine = create_engine('mysql+pymysql://root:123456@localhost/test') DBsession = sessionmaker(bind=engine) session = DBsession() a = session.query(Student).filter(Student.id == 1001) b = session.query(Student).filter_by(id=1001) for x in a: print(x.id, x.name, x.age, x.address) for i in b: print(i.id, i.name, i.age, i.address) |
輸出結果app
1 2 |
1001 Alice 25 anhui 1001 Alice 25 anhui |
filter()
和filter_by()
區別
filter能夠像寫sql的where條件那樣寫>、<等條件,但引用列名時,須要經過類名.屬性名
的方式。
filter_by能夠使用python的正常參數傳遞方法傳遞條件,指定列名時,不須要額外指定類名,參數名對應類中的屬性名,不能使用>、<等條件。
當使用filter的時候條件之間是使用==
,filter_by使用的是=
。
filter不支持組合查詢,只能連續調用filter變相實現。filter_by的參數是**kwargs,直接支持組合查詢。框架
1 2 3 4 |
filters = {'id':1002, 'name':'Bob'} b = session.query(Student).filter_by(**filters) for i in b: print(i.id, i.name, i.age, i.address) |
輸出結果
1 |
1002 Bob 69 beijing |
1 2 3 4 |
a = session.query(Student).filter(Student.id > 1001).all() print(a) for x in a: print(x.id, x.name, x.age, x.address) |
輸出結果
1 2 3 |
[<db.orm2.Student object at 0x00000197ECC759E8>, <db.orm2.Student object at 0x00000197ECC75A58>] 1002 Bob 69 beijing 1003 Cerry 14 jiangsu |
1 2 3 |
a = session.query(Student).filter(Student.id == 1001).one() print(a) print(a.id, a.name, a.age, a.address) |
輸出結果
1 2 |
<db.orm2.Student object at 0x000001B7C57E7908> 1001 Alice 25 anhui |
1 2 3 |
a = session.query(Student).filter(Student.id > 1001).first() print(a) print(a.id, a.name, a.age, a.address) |
輸出結果
1 2 |
<db.orm2.Student object at 0x000001C63E536B00> 1002 Bob 69 beijing |
metadata = MetaData(engine)
綁定一個數據源的metadata。metadata.create_all(engine)
建立表,該操做會先判斷表是否存在,若存在則不建立。Table.__init__(self, name, metadata,*args, **kwargs)
Column
是列定義Column.__init__(self, name, type_, *args, **kwargs)
*args
參數定義**kwargs
參數定義SQLAlchemy
中,數據庫的查詢操做是經過Query對象來實現的,而Session提供了建立Query對象的接口。Query對象返回的結果是一組同一映射(Identity Map)對象組成的集合。事實上,集合中的一個對象,對應於數據庫表中的一行(即一條記錄)。所謂同一映射,是指每一個對象有一個惟一的ID。若是兩個對象(的引用)ID相同,則認爲它們對應的是相同的對象。 1 2 3 4 |
from sqlalchemy.orm import sessionmaker DBSession = sessionmaker(bind=engine) session = DBSession() |
經過sessionmake方法建立一個Session工廠,而後在調用工廠的方法來實例化一個Session對象。
要了解更多關於SQLAlchemy
內容能夠點擊SQLAlchemy Documentation查看官方介紹。
分享