SQlAlchemy簡單使用
sqlalchemy介紹
SQLAlchemy的是Python的SQL工具包和對象關系映射器媳友,讓應用程序開發(fā)人員可以使用上SQL的強大功能和靈活性刃唤。
它提供了一套完整的企業(yè)級持久化模式戈盈,專為高效率和高性能的數(shù)據(jù)庫訪問而設計著洼,簡單易用用液肌,專門為Python語言而準備啥繁。
SQLAlchemy的理念
SQL數(shù)據(jù)庫與對象集合目標不同唱蒸,它需要關注更大的數(shù)據(jù)容量與更高的性能;而對象集合則和數(shù)據(jù)表或數(shù)據(jù)行的目標不同幻林,它需要更好的數(shù)據(jù)抽象终吼。 SQLAlchemy設計的目的镀赌,就是適配這兩個原則。
SQLAlchemy把數(shù)據(jù)庫當作是一個關系型代數(shù)引擎际跪,不只是數(shù)據(jù)表的一個集合商佛。數(shù)據(jù)行不僅可以從數(shù)據(jù)表中查詢出來,也可以從數(shù)據(jù)表關聯(lián)后成形成的邏輯數(shù)據(jù)表和其他的查詢語句結果中進行查詢;這些元素可以組合形成更大的數(shù)據(jù)結構姆打。 SQLAlchemy的表達式語言就是建立在這個核心概念之上的良姆。
SQLAlchemy組件中最有名的是它的對象關系映射器(ORM),是一個提供數(shù)據(jù)映射器模式的可選組件幔戏,利用這個組件玛追,類可以以開放式的多種方式映射到數(shù)據(jù)庫上,允許對象模型的設計和數(shù)據(jù)庫架構的設計闲延,一開始就以分離方式進行各自的開發(fā)痊剖。實現(xiàn)松耦合的架構.
連接數(shù)據(jù)庫
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
DB_CONNECT_STRING = 'mysql+mysqldb://root:123@localhost/mydb?charset=utf8'
engine = create_engine(DB_CONNECT_STRING)
DB_Session = sessionmaker(bind=engine)
session = DB_Session()
上面的DB_CONNECT_STRING是連接數(shù)據(jù)庫的路徑,這個路徑也就是database_urls
包含了使用的數(shù)據(jù)庫驅動以及數(shù)據(jù)庫的連接信息等.一般格式是:dialect+driver://username:password@host:port/database
下面給出其他形式的數(shù)據(jù)庫連接示例:
# default
engine = create_engine('postgresql://scott:tiger@localhost/mydatabase')
# psycopg2
engine = create_engine('postgresql+psycopg2://scott:tiger@localhost/mydatabase')
# pg8000
engine = create_engine('postgresql+pg8000://scott:tiger@localhost/mydatabase')
# default
engine = create_engine('mysql://scott:tiger@localhost/foo')
# mysql-python
engine = create_engine('mysql+mysqldb://scott:tiger@localhost/foo')
# MySQL-connector-python
engine = create_engine('mysql+mysqlconnector://scott:tiger@localhost/foo')
# OurSQL
engine = create_engine('mysql+oursql://scott:tiger@localhost/foo')
直接操作sql
sql= 'show tables'
session.execute(sql)
result = session.excute(sql).fetchall()
sql = 'create database test'
session.excute(sql)
以上使用sqlalchemy直接執(zhí)行sql語句,這和mysql-python沒有任何區(qū)別.當然,需要注意在事務操作中,記得commit
.在操作很復雜的sql語句,不能映射到對應的ORM上,這是備用選項.
下面開始介紹sqlalchemy的ORM.從數(shù)據(jù)庫的增刪查改.
關聯(lián)一個數(shù)據(jù)表
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, String, Integer
engine = create_engine('mysql+mysqldb://root:youdi@localhost:3306/alchemy?charset=utf8')
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column('username',String(64), nullable=False)
password = Column(String(64), nullable=False)
email = Column(String(64), nullable=False)
def __repr__(self):
return '%s(%r)' % (self.__class__.__name__, self.username)
插入數(shù)據(jù)
import User
from sqlalchemy.orm import sessionmaker
session = sessionmaker(bind=engine)
mysql = session()
user1 = User()
user1.id = 2
user1.name = 'hello'
user1.email = '123@gmail.net'
user1.password = 'password'
mysql.add(user1)
user2 = User(id=3,name='youmi',password='1234',email='12@you.net')
mysql.add(user2)
mysql.commit()
上面插入了兩條數(shù)據(jù)
mysql> select * from users;
+----+----------+----------+---------------+
| id | username | password | email |
+----+----------+----------+---------------+
| 2 | hello | password | 123@gmail.net |
| 3 | youmi | 1234 | 12@you.net |
+----+----------+----------+---------------+
2 rows in set (0.02 sec)
查詢表中的數(shù)據(jù)
1.查詢所有的數(shù)據(jù)
如同select * from tb_name
query = mysql.query(User)
sql = str(query) # 執(zhí)行的sql語句
sql = query.statement # 執(zhí)行的sql語句
users_name = []
for i in query: #遍歷時查詢
users_name.append(i.name)
query.all() #返回所有對象的列表
query.first() #返回第一個對象,記錄不存在時,first() 會返回 None
query.one() # 不存在垒玲,或有多行記錄時會拋出異常
另外,query也可以使用User直接獲得
query = User.query
2.顯示指定字段的數(shù)據(jù)
如同: select name,id from users
names = mysql.query(User.name)
names.all() #每行都是一個元組
3.篩選條件
limit
mysql.query(User).limit(10)
User.query.limit(10)
offset
offset = 10
mysql.query(User).offset(offset).limit(10)
# or
User.query.offset(offset).limit(10)
oder by
mysql.query(User).order_by('id')
mysql.query(User).order_by(User.id.desc())
mysql.query(User).order_by('id asc')
mysql.query(User).order_by(User.name.desc(),User.id)
filter
sql中的where后面的條件
mysql.query(User).filter(User.id == 1).scalar()
# or 使用字面量
mysql.query(User).filter('id = 1').scalar()
# 多個條件
mysql.query(User).filter(User.id > 1,User.name != 'youmi').scalar()
# in條件
mysql.query(User).filter(User.id.in_((1,2,3))).scalar()
# or條件需要導入or_()函數(shù)
mysql.query(User).filter(or_(User.id > 1,User.name != 'youmi')).scalar()
補充(所有的額外函數(shù)):
其中func
映射到sql中的很多函數(shù),如:count
,sum
,now
,current_timestamp
,md5
等等,
其他的函數(shù),有case
對應sql中when case
from .sql import (
alias,
and_,
asc,
between,
bindparam,
case,
cast,
collate,
delete,
desc,
distinct,
except_,
except_all,
exists,
extract,
false,
func,
insert,
intersect,
intersect_all,
join,
literal,
literal_column,
modifier,
not_,
null,
or_,
outerjoin,
outparam,
over,
select,
subquery,
text,
true,
tuple_,
type_coerce,
union,
union_all,
update,
)
4.聯(lián)表查詢(join)
INNER JOIN
query = User.query.join(Group, User.gid == Group.id)
.filter(User.id != None,"is_superuser & 1 = 1")
.order_by(User.last_edit.asc()).limit(10)
LEFT JOIN
query = User.query.outerjoin(Group, User.gid == Group.id)
.filter(User.id != None,"is_superuser & 1 = 1")
.order_by(User.last_edit.asc()).limit(10)
RIGHT JOIN
query = User.query.outerjoin(Group, User.gid == Group.id)
.filter(User.id != None,"is_superuser & 1 = 1")
.order_by(User.last_edit.asc()).limit(10)
其他的連接方式,需要自己指定參數(shù),可以靈活的操作:
def join(self, right, onclause=None, isouter=False, join_to_left=None):
return _ORMJoin(self, right, onclause, isouter)
def outerjoin(self, right, onclause=None, join_to_left=None):
return _ORMJoin(self, right, onclause, True)
修改數(shù)據(jù)
mysql.query(User).filter(User.id == 1).update({User.name:'youmi'})
# or
user = mysql.query(User).filter(User.id == 1)
user.name = 'test'
mysql.flush() #寫入數(shù)據(jù)庫,但并沒有提交
刪除數(shù)據(jù)
mysql.query(User).filter(User.id == 1).delete()
mysql.commit()
不過相比Django的ORM.sqlalchemy對sql的支持更好.
上面只是簡單的介紹了sqlalchemy的增刪查改,需要更加深入的特性,可以查看官方文檔,或者查看源碼.