python sqlalchemy 连接池_python连接数据库使用SQLAlchemy

#本脚本兼容了python2.x和3.x版本,使用SQLAlchemy ORM连接sqlserver或者MySQL,实现一个用户洗牌的应用

from os.path importdirnameimportpymysqlfrom pymysql.err importInternalErrorfrom random importrandrangefrom distutils.log importwarn as printffrom sqlalchemy importColumn,Integer,String,create_engine,exc,ormfrom sqlalchemy.ext.declarative importdeclarative_base#导入本地应用模块(ushuffle_dbU)必要的常量和工具函数,这是为了避免到处复制、黏贴相同的代码

from ushuffle_dbU importDBNAME,NAMELEN,randName,FIELDS,tformat,cformat,setup#dialect+driver://username:password@host:port/database

DSNs ={'mysql':'mysql+pymysql://root:Jwxjs123456@localhost/%s' %DBNAME,'sqllite':'sqllite:///:memory:','sql server':'mssql+pymssql://sa:Jwxjs123456@localhost/%s' %DBNAME,

}#SQLALchemy的声明层。

base =declarative_base()class Users(base):#继承Base类

__tablename__ = 'users' #映射的数据库表名

login =Column(String(NAMELEN))

userid= Column(Integer,primary_key =True)

projid=Column(Integer)def __str__(self): #返回易于阅读的数据行的字符串格式

return ''.join(map(tformat,(self.login,self.userid,self.projid)))classSQLALchemyTest(object):#初始化函数尽可能的得到一个可用的数据库,保存其连接

def __init__(self,dsn):try:

eng= create_engine(dsn)#,echo = True)#尝试使用dsn创建数据库引擎,echo设置为True可使得我们能看到ORM生成的SQL语句

printf('*****创建数据库引擎成功')exceptImportError:raise RuntimeError()#创建失败。一般来说,引擎创建失败意味着SQLAlchemy不支持所选的数据库,会抛出ImportError

try:

eng.connect()#如果数据库引擎创建成功,则尝试创建数据库连接

printf('*****连接数据库%s成功' %DBNAME)except (exc.InternalError,InternalError):#如果创建连接失败,一般意味着数据库本身不可达。此例中是因为目标数据库不存在

eng = create_engine( dirname(dsn),echo = True)#dirname返回dsn的目录。其实就是os.path.split(path)的第一个元素。效果相当于dsn去掉数据库

eng.execute('create database %s' %DBNAME).close()

printf('新建数据库%s成功' %DBNAME)

eng.create_engine(dsn,echo=True)

printf('连接数据库%s成功' %DBNAME)#创建数据库引擎连接之后,需要创建一个会话对象Session,其实是一个factory。

#sessionmaker()也可以在create_engine之前创建,然后等到数据库引擎连接创建之后,调用Session.configure(bind=)实现绑定

Session = orm.sessionmaker(bind=eng)#Session()可以创建一个绑定到数据库的对象。但是到此为止,它还没有打开任何的连接。

#当它第一次被调用的时候,会尝试从数据库引擎连接池中检索一个链接,该连接会一直被持有直到所有的任务都被提交或者Session对象被关闭

self.ses =Session()#将用户的表和数据库引擎作为 实例的属性保存下来。意味着这张表的所有操作都会被绑定到这个指定的引擎中。

self.users = Users.__table__self.eng= self.users.metadata.bind = eng#引擎和表的元数据进行了额外的绑定,意味着这张表的所有操作都会绑定到这个指定的引擎中

definsert(self):

self.ses.add_all(Users(login= who,userid=userid,projid=randrange(1,5)) for who,userid inrandName())

self.ses.commit()defupdate(self):

fr= randrange(1,5)

to= randrange(1,5)

i= -1users= self.ses.query(Users).filter_by(projid =fr).all()for i ,user inenumerate(users):

user.projid=to

self.ses.commit()

printf('\n %s 个用户名从 %s 更改到 %s' % (i+1,fr,to))defdelete(self):

rm= randrange(1,5)

i= -1users= self.ses.query(Users).filter_by(projid =rm).all()for i,user inenumerate(users):

self.ses.delete(user)

self.ses.commit()

printf('组号为%s的共%s个用户被删除' % (rm,i+1))deffinish(self):

self.ses.connection().close()defdbDump(self):

printf('\n%s' % ''.join(map(cformat,FIELDS)))

users=self.ses.query(Users).all()for user inusers:

printf(user)

self.ses.commit()def __getattr__(self,attr):#drop和create方法实际上只需要调用表的drop()和create()方法即可,不用我们自己单独编写。这里使用委托机制——当属性查找失败的时候会调用__getattr__()方法。

return getattr(self.users,attr)#使用help(getattr)来获取帮助。getattr()获取对象的属性,getattr(x,'y')相当于执行x.y。

defmain():

printf('连接%s数据库' %DBNAME)

db=setup()if db not inDSNs:

printf('\n ERROR:%s 数据库不被支持,程序退出')return

try:

orm=SQLALchemyTest(DSNs[db])exceptRuntimeError:

printf('\nERROR: %s 数据库不支持,程序退出')

printf('\n***创建users表()')

orm.drop(checkfirst= True)#orm.create()

printf('\n***创建users表,成功!!!')

printf('%%%插入数据')

orm.insert()

orm.dbDump()

printf('\n随机将用户进行分组')

orm.update()

orm.dbDump()

printf('\n !!!随机删除用户')

orm.delete()

orm.dbDump()

printf('\n***删除表格')

orm.drop()

printf('\n关闭数据库连接!')

orm.finish()if __name__ == '__main__':

main()

你可能感兴趣的:(python,sqlalchemy,连接池)