工作需要,用到了sqlalchemy, 经过近一个月的不断学习和探索实践,现在整理一下,以免将来没地方找。
sqlalchemy有两种方法,一种是session-mapper的方式,称为orm方式,另一种就是原生的select等sql语句,称之为core方式。
下面的讲解我们统一把数据库的相关操作封装在一个类里面。
先来说第一种:
-
from sqlalchemy import create_engine
-
from sqlalchemy.ext.declarative import declarative_base
-
from sqlalchemy.dialects.mysql import INTEGER, DATETIME, REAL, TEXT, VARCHAR
-
from sqlalchemy import Table, Column, ForeignKey, MetaData
-
from sqlalchemy.orm import mapper, sessionmaker
-
from sqlalchemy import func
-
import re
-
import hashlib
-
import os, sys
-
import time, datetime
-
class SelectData():
-
def __init__(self):
-
s1 = "mysql+mysqldb://"
-
server = "root:123456@localhost:3306/test"
-
s2 = "?use_unicode=0&charset=utf8"
-
connectserver = s1 + server + s2
-
self.engine = create_engine(connectserver, encoding = 'utf-8', echo = False)
-
self.Base = MetaData()
-
self.user= Table(
-
'user', self.Base,
-
Column('id', INTEGER, primary_key = True),
-
Column('name', TEXT)
-
Column('passwd', TEXT)
-
)
-
self.client = Table(
-
'client', self.Base,
-
Column('id', INTEGER, primary_key = True),
-
Column('name', TEXT),
-
Column('id_user', INTEGER),
-
Column('reserved_int', INTEGER),
-
Column('reserved_varchar', VARCHAR(200))
-
)
-
self.Base.create_all(self.engine)#create_all可以自动检测表是否已经建立,非常方便
-
self.Session = sessionmaker() #创建了一个自定义了的 Session类
-
self.Session.configure(bind = self.engine) #将创建的数据库连接关联到这个session
下面的函数是单表的查询插入更新展示:
-
def insert_function(self):
-
session = self.Session()
-
class User(object): pass
-
mapper(User, self.user)
-
class Client(object): pass
-
mapper(Client, self.client)
-
#select方式:
-
ret = session.query(User).filter(User.name == "admin").first()
-
if ret is None:
-
#添加新的字段
-
user = User()
-
user.name = "admin"
-
user.passwd = CountMd5("123456")#此处CountMd5()是自己写的一个计算md5值的函数
-
session.add(user)
-
session.flush()
-
#session.commit()
-
#获取刚刚插入数据的自增主键id
-
id_usr = user.id
-
else:
-
id_usr = ret.id
-
ret2 = session.query(Client).filter_by(id_user = id_usr).first()
-
if ret2 is None:
-
client = Client()
-
client.name = "Chocolate"
-
client.id_user = id_usr
-
client.session.add(client)
-
session.flush()
-
session.commit()
-
else:
-
#使用update:
-
session.query(Client).filter_by(id_user = id_usr).update({"name": "Chocolate", "id_user":id_usr})
-
session.flush()
-
session.commit()
-
session.close()
下面是多表联合查询:
-
#多表联合查询
-
def testfun2(self, partname, pageindex):
-
session = self.Session()
-
class User(object): pass
-
mapper(User, self.user)
-
class Client(object): pass
-
mapper(Client, self.client)
-
pageval = (pageindex - 1) * 10
-
#这里面一个是like的用法,一个是只显示某10条
-
ret = self.session.query(User)\
-
.join(Client, Client.id_user == User.id )\
-
.filter(User.name.like('%' + partname + '%'))\
-
.offset().limit(10).all()
-
if ret is None:
-
return None
-
else:
-
for k in ret:
-
print k.name, k.passwd
-
session.close()
下面是删除表的内容的用法:
-
#删除表的全部内容,不删除表
-
def delete_func(self):
-
session = self.Session()
-
class User(object): pass
-
mapper(User, self.user)
-
class Client(object): pass
-
mapper(Client, self.client)
-
session.query(Client).delete()
-
session.query(User).delete()
-
session.commit()
-
session.close()
上面就是orm的方式了,这个方式要特别注意的地方就是,session的问题,因为session是有个有效期的,如果我们把session在init函数里面做成全局变量self.session,那么就会出现数据库实时更新插入的值这里面查询不到,所以,对于session的态度,我们是用到再新建,用完手动关闭。
然后下面我们来讲一下第二种方式,core的方式:
上面建表的部分是一样的,只不过要把建完表之后session那一块替换为:
-
self.Base.create_all(self.engine)
-
self.conn = self.engine.connect()
定义一个关闭数据库连接的函数:
-
def close(self):
-
self.conn.close()
下面是简单的一些基本用法:
包含了查询,插入和更新。
-
def resetpwd(self, passwdm):
-
sel = select([self.user]).where(self.user.c.name == "admin")
-
ret = self.conn.execute(sel).fetchone()
-
if ret is None:
-
ins = self.user.insert().values(name = "admin", passwd = passwdm)
-
self.conn.execute(ins)
-
else:
-
updpwd = self.user.update().values(name = "admin", passwd = passwdm).where(self.user.c.name == "admin")
-
self.conn.execute(updpwd)
execute会自动commit,不用我们去手动做。这种core的方式要注意的地方就是表后面有个.c,如self.user.c.name,我也不知道为什么有这个c,看官网的用例上都是这样的,如果不加的话就不正确。所以还是屈从权威吧。问题解决了才最重要。
--------------------- 本文来自 Daisy_Echo 的优快云 博客 ,全文地址请点击:https://blog.youkuaiyun.com/ichocolatekapa/article/details/23946263?utm_source=copy