SQLAlchemy之mysql使用手册

原文链接:https://blog.csdn.net/counsellor/article/details/60139569

【前言】

使用python处理mysql数据库相关的业务,一般都是使用库MySQLdb直接调用sql语句。感觉很low,换一个SQLAlchemy上手。不但是耍酷,之前些flask代码时就很惊讶基本看不到对数据库的操作,其使用的就是修改过的SQLAlchemy,好处是直接操作数据库表对象,即ORM对象关系映射管理,性能会慢些,但在1-2倍的时间,在可以接受的范围。

安装

pip install sqlalchemy
pip install --egg mysql-connector-python-rf
pip install sqlacodegen
  • 1
  • 2
  • 3

生成models

  1. 方法一: 自己根据SQLAlchemy的docs写model,比如一对多,多对一等复杂的表模型。(SQLAlchemy的文档非常详细,就跟天书一样,真心懒得看。还是flask-sqlalchemy的文档简洁明了,可以参考的)

  2. 方法二: 使用sqlacodegen从数据库逆向出models.py

$ sqlacodegen --noviews --noconstraints --noindexes \
--outfile ./models.py mysql://username:password@localhost:3399/dbname 
  • 1
  • 2

这里需要注意下,使用–noviews, –noconstraints, –noindexes,这3个选项是去掉视图,约束和所以,基本用不到。反之,不去带着些文件结构的话可能会报错,比如views找不到数据。

数据库表-User

id name age
1 ‘Tom’ 22
2 ‘Jim’ 21
3 ‘Lucy’ 22

对应的models.py

# 导入:
from sqlalchemy import Column, String, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# 创建对象的基类:
Base = declarative_base()

# 定义User对象:
class User(Base):
    # 表的名字:
    __tablename__ = 'user'

    # 表的结构:
    id = Column(String(20), primary_key=True)
    name = Column(String(20))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

基本使用

首先要创建engine,它代表一种数据库连接资源。可以通过engine船舰connect和session完成事务的提交。对于使用os.fork或者multiprocessing的多进程应用来说,通常需要为紫禁城提供单独的engine。

mysql:

engine = create_engine('mysql://scott:tiger@localhost/test')

#比较好的习惯是现实销毁引擎,会有助于python的垃圾回收
engine.dispose()
  • 1
  • 2
  • 3
  • 4

sqlite:

engine = create_engine('sqlite:///file.db')
  • 1

查询记录

那么我们怎么从数据库中查询数据?为此,SQLAlchemy 在您的 Model 类上提供了 query 属性。当您访问它时,您会得到一个新的所有记录的查询对象。在使用 all() 或者 first() 发起查询之前可以使用方法 filter() 来过滤记录。如果您想要用主键查询的话,也可以使用 get()。

connect:

connection = engine.connect()
result = connection.execute("select username from users")
for row in result:
    print("username:", row['username'])
connection.close()
  • 1
  • 2
  • 3
  • 4
  • 5

Session:

# 创建DBSession类型:
DBSession = sessionmaker(bind=engine)
# 创建Query查询,filter是where条件,最后调用one()返回唯一行,如果调用all()则返回所有行:
user = session.query(User).filter(User.id=='5').one()
# 打印类型和对象的name属性:
print 'type:', type(user)
print 'name:', user.name
# 关闭Session:
session.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

使用更复杂的表达式查询一些用户:

>>> User.query.filter(User.email.endswith('@example.com')).all()
[<User u'admin'>, <User u'guest'>]
  • 1
  • 2

按某种规则对用户排序:

>>> User.query.order_by(User.username)
[<User u'admin'>, <User u'guest'>, <User u'peter'>]
  • 1
  • 2

限制返回用户的数量:

>>> User.query.limit(1).all()
[<User u'admin'>]
  • 1
  • 2

用主键查询用户:

>>> User.query.get(1)
<User u'admin'>
  • 1
  • 2

打印查询结果的全部元素:

for u in session.query(User).all():
    print u.__dict__
  • 1
  • 2

插入记录

插入记录ret = session.add(),其中ret的值永远是none,不用看。

Session:

try:
    sess = Session()
    sess.add(User())
    sess.commit()
except gevent.Timeout:
    sess.invalidate()
    raise
except:
    sess.rollback()
    raise
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

删除记录

删除记录是十分类似的,使用 delete() 代替 add():

>>> db.session.delete(me)
>>> db.session.commit()
  • 1
  • 2

更改记录

基本思路是先filter到需要的行集合,再修改里面的值。这里有4种方式:

1) user.no_of_logins += 1
   session.commit()

2) session.query().\
       filter(User.username == form.username.data).\
       update({"no_of_logins": (User.no_of_logins +1)})
   session.commit()

3) conn = engine.connect()
   stmt = User.update().\
       values(User.no_of_logins = (User.no_of_logins + 1)).\
       where(User.username == form.username.data)
   conn.execute(stmt)

4) setattr(user, 'no_of_logins', user.no_of_logins+1)
   session.commit()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

事务

事物就是有一系列动作一气呵成,如果中间失败了,前面的动作不会生效。满足ACID特性。

最简单的例子就是转账,我给你转10块钱后台需要做两件事,先在我账户中减去10,再在你的账户里加10。想想如果这件事不用事务处理,我卡里减了10块钱,而转你钱没有成功,这十块钱就莫名消失了哈。

connection = engine.connect()
trans = connection.begin()
try:
    r1 = connection.execute(table1.select())
    connection.execute(table1.insert(), col1=7, col2='this is some data')
    trans.commit()
except:
    #一旦出错就回滚
    trans.rollback()
    raise
connection.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

参考文献

stackoverflow.com: Convert sqlalchemy row object to python dict

猜你喜欢

转载自blog.csdn.net/fuchen58/article/details/81182394