当前位置:   article > 正文

Python操作MySQL之SQLAlchemy_python mysql sqlalchemy

python mysql sqlalchemy

概述

SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取执行结果。

 

ORM技术

数据库表是一个二维表,包含多行多列。把一个表的内容用Python的数据结构表示出来的话,可以用一个list表示多行,list的每一个元素是tuple,表示一行记录。比如,包含id和name的user表:

  1. [
  2. ('1', 'Michael'),
  3. ('2', 'Bob'),
  4. ('3', 'Adam')
  5. ]

Python的DB-API返回的数据结构就是像上面这样表示的。

但是用tuple表示一行很难看出表的结构。如果把一个tuple用class实例来表示,就可以更容易地看出表的结构来:

  1. class User(object):
  2. def __init__(self, id, name):
  3. self.id = id
  4. self.name = name
  5. [
  6. User('1', 'Michael'),
  7. User('2', 'Bob'),
  8. User('3', 'Adam')
  9. ]

上述就是ORM技术:Object-Relational Mapping,把关系数据库的表结构映射到对象上。

SQLAlchemy

SQLAlchemy-初始化连接

SQLAlchemy本身无法操作数据库,其必须依赖pymsql等第三方插件,Dialect用于和数据API进行交流,根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作。

  1. # pymysql
  2. DB_CONNECT_STRING = 'mysql+pymysql://root:123456@127.0.0.1:3306/db_stable'
  3. # MySQL-Python
  4. DB_CONNECT_STRING = 'mysql+mysqldb://root:123456@127.0.0.1:3306/db_stable'
  5. # MySQL-Connector
  6. DB_CONNECT_STRING = 'mysql+mysqlconnector://root:123456@127.0.0.1:3306/db_stable'

create_engine()返回一个Engine的实例,并且它表示通过数据库语法处理细节的核心接口,在这种情况下,数据库语法将会被解释成python的类方法。

echo参数为True时,会显示每条执行的SQL语句,可以关闭。

  1. from sqlalchemy import create_engine
  2. # 初始化数据库连接
  3. DB_CONNECT_STRING = 'mysql+pymysql://root:123456@127.0.0.1:3306/db_stable'
  4. Engine = create_engine(DB_CONNECT_STRING, echo=True, pool_recycle=3600)

 

SQLAlchemy-创建表

__tablename__ 属性:数据库中该表的名称

  1. from sqlalchemy.ext.declarative import declarative_base
  2. from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
  3. from sqlalchemy.orm import sessionmaker, relationship
  4. from sqlalchemy import create_engine
  5. # 创建对象的基类,declarative_base() 创建了一个 Base类,这个类的子类可以自动与一个表关联。
  6. Base = declarative_base()
  7. # 创建单表
  8. class Params(Base):
  9. __tablename__ = "t_params"
  10. __table_arge__ = {"extend_existing": True, "useexisting": True}
  11. id = Column(Integer, primary_key=True, autoincrement=True)
  12. package = Column(CHAR(255), nullable=False)
  13. project = Column(CHAR(255), nullable=False)
  14. platform = Column(CHAR(255), nullable=False)
  15. prefix = Column(CHAR(255))
  16. activity = Column(CHAR(255))
  17. # 一对多,外键ForeignKey
  18. class Devices(Base):
  19. __tablename__ = "t_devices"
  20. __table_arge__ = {"extend_existing": True, "useexisting": True}
  21. id = Column(Integer, primary_key=True, autoincrement=True)
  22. sn = Column(CHAR(255), nullable=False)
  23. platform = Column(CHAR(50), nullable=False)
  24. idfa = Column(CHAR(255))
  25. uuid = Column(CHAR(255))
  26. unionid = Column(CHAR(255))
  27. product = Column(CHAR(255))
  28. os_version = Column(CHAR(255))
  29. class Jobs(Base):
  30. __tablename__ = "t_jobs"
  31. __table_arge__ = {"extend_existing": True, "useexisting": True}
  32. id = Column(Integer, autoincrement=True, primary_key=True)
  33. device_id = Column(Integer, ForeignKey("t_devices.id"))
  34. user_name = Column(CHAR(255))
  35. business = Column(CHAR(255))
  36. version = Column(CHAR(50))
  37. job_type = Column(CHAR(50))
  38. submit_time = Column(DATETIME)
  39. end_time = Column(DATETIME)
  40. job_status = Column(Integer)
  41. config_name = Column(CHAR(255))
  42. # 多对多
  43. class ServerToGroup(Base):
  44. __tablename__ = 'servertogroup'
  45. nid = Column(Integer, primary_key=True, autoincrement=True)
  46. server_id = Column(Integer, ForeignKey('server.id'))
  47. group_id = Column(Integer, ForeignKey('group.id'))
  48. class Group(Base):
  49. __tablename__ = 'group'
  50. id = Column(Integer, primary_key=True)
  51. name = Column(String(64), unique=True, nullable=False)
  52. class Server(Base):
  53. __tablename__ = 'server'
  54. id = Column(Integer, primary_key=True, autoincrement=True)
  55. hostname = Column(String(64), unique=True, nullable=False)
  56. port = Column(Integer, default=22)

多对多关系:需要转换成1对多关系,需要一张中间表来转换,这张中间表里面需要存放学生表里面的主键和课程表里面的主键,此时学生与中间表示1对多关系,课程与中间表是1对多关系,学生与课程是多对多关系。

 

SQLAlchemy-创建会话(操作表)

sessionmaker() 会生成一个数据库会话类。这个类的实例可以当成一个数据库连接,它同时还记录了一些查询的数据,并决定什么时候执行 SQL 语句。

  1. from sqlalchemy.orm import sessionmaker
  2. # 创建Session对象(mysql操作对象)
  3. Session = sessionmaker(bind=Engine, autoflush=True, expire_on_commit=True)

SQLAlchemy-增、删、改、查

新增:

  1. @auto_close
  2. def insert_job(body, session=None):
  3. item = Jobs(**body)
  4. session.add(item)
  5. session.flush()

删除:

  1. @auto_close
  2. def delete_job(data, jobId, session=None):
  3. session.query(Jobs).filter(Jobs.id == jobId).delete

更新:

  1. @auto_close
  2. def update_job(data, jobId, session=None):
  3. session.query(Jobs).filter(Jobs.id == jobId).update(data)

查询

  1. @auto_close
  2. def get_jobId(sub_time, session=None):
  3. item = session.query(Jobs).filter(Jobs.submit_time == sub_time).first()
  4. jobId = item.id
  5. return jobId

注意:

1.通过Session的query()方法创建一个查询对象。这个函数的参数数量是可变的,参数可以是任何类或者是类的描述的集合。

2.查询出来的数据sqlalchemy直接给映射成一个对象(或者是每个元素为这种对象的列表),对象和创建表时候的class是一致的,可以直接通过对象的属性直接调用。如:item.id

3.first():返回查询的第一个结果,如果没有结果,则返回None

   all():以列表形式返回查询的所有结果

   count():返回查询结果的数量

 

SQLAlchemy-查询

查询过滤器

使用举例:

filter():过滤表的条件

filter: 可以像写 sql 的 where 条件那样写 > < 等条件,但引用列名时,需要通过"类名.属性名"的方式。

filter_by: 可以使用 python 的正常参数传递方法传递条件,指定列名时,不需要额外指定类名。参数名对应类中的属性名,但似乎不能使用 > < 等条件。

当使用filter的时候条件之间是使用“==",fitler_by使用的是"="。

user1 = session.query(User).filter_by(id=1).first()

user1 = session.query(User).filter(User.id==1).first()

  1. # 条件:== 、!=、like、in、非、>、between
  2. ret = session.query(Users).filter(Users.name =='alex').all()
  3. ret = session.query(Users).filter(Users.name !='alex').all()
  4. ret = session.query(Users).filter(Users.name.like("%alex%")).all()
  5. ret = session.query(Users).filter(Users.id.in_([1,3,4])).all()
  6. ret = session.query(Users).filter(~Users.id.in_([1,3,4])).all() # not in ~为通配符非
  7. ret = session.query(Users).filter(~Users.name.like('e%')).all()
  8. ret = session.query(Users).filter(Users.id > 1, Users.name == 'eric').all()
  9. ret = session.query(Users).filter(Users.id.between(1, 3), Users.name == 'eric').all()
  10. # AND 以下两个功能一致
  11. ret = session.query(Users).filter(and_(Users.name == 'fengxiaoqing', Users.id ==10001)).all()
  12. ret = session.query(Users).filter(Users.name == 'fengxiaoqing').filter(Users.address == 'chengde').all()
  13. # OR
  14. ret = session.query(Users).filter(or_(Users.name == 'fengxiaoqing', Users.age ==18)).all()
  15. ret = session.query(Users).filter(
  16. or_(
  17. Users.id < 2,
  18. and_(Users.name == 'eric', Users.id > 3),
  19. Users.extra != ""
  20. )).all()

其余函数:

  1. # order_by:排序 limit:指定行数
  2. item = session.query(Jobs).order_by(Jobs.id).limit(4)
  3. # desc:倒序显示 asc:升序
  4. item = session.query(Jobs).order_by(Jobs.id.desc(),Jobs.device_id.asc())
  5. # group_by
  6. ret = session.query(Users).group_by(Users.extra).all()
  7. # func
  8. ret = session.query(
  9. func.max(Users.id),
  10. func.sum(Users.id),
  11. func.min(Users.id)).group_by(Users.name).all()
  12. ret = session.query(
  13. func.max(Users.id),
  14. func.sum(Users.id),
  15. func.min(Users.id)).group_by(Users.name).having(func.min(Users.id) >2).all()

连接查询join

  1. ret = session.query(Users, Favor).filter(Users.id == Favor.nid).all()
  2. ret = session.query(Person).join(Favor).all()
  3. ret = session.query(Person).join(Favor, isouter=True).all()

子查询

ret = session.query(Users).filter(Users.id.in_(session.query(Users.id).filter_by(name='eric'))).all()

联合查询union

  1. q1 = session.query(Users.name).filter(Users.id > 2)
  2. q2 = session.query(Favor.caption).filter(Favor.nid < 2)
  3. ret = q1.union(q2).all()
  4. q1 = session.query(Users.name).filter(Users.id > 2)
  5. q2 = session.query(Favor.caption).filter(Favor.nid < 2)
  6. ret = q1.union_all(q2).all()

 

参考

https://www.cnblogs.com/ccorz/p/5711955.html

https://blog.csdn.net/wuqing942274053/article/details/72571650

https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/0014021031294178f993c85204e4d1b81ab032070641ce5000

mysql查询操作:

https://blog.csdn.net/u012867040/article/details/54380900

https://blog.csdn.net/u012867040/article/details/59115271

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/527517
推荐阅读
相关标签
  

闽ICP备14008679号