设为首页 收藏本站
查看: 515|回复: 0

[经验分享] python操作数据库 - SQLAlchemy

[复制链接]

尚未签到

发表于 2018-8-11 14:22:38 | 显示全部楼层 |阅读模式
  ORM简介

  ORM全称是Object>  核心就是一个class对应一张表。
  SQLAlchemy现在已经是python中最流行的ORM框架。
  ORM优点:
  1、隐藏数据库实现,让业务代码只访问对象而不是数据库表
  2、良好的数据库操作接口,简单、学习成本低
  3、动态数据表映射,表结构改变时,减少代码修改量
  4、方便引入缓存功能
  SQLAlchemy结构
DSC0000.jpg

  SQLAlchemy ORM详解
yum install -y python-sqlalchemy # 或pip install sqlalchemy  
yum install -y python-libs  # 安装sqlite3
  
pip install sqlalchemy-utils # 安装sqlalchemy 一些工具类
  sqlite数据库操作: http://blog.chinaunix.net/uid-26833883-id-3239313.html
  创建数据库及表结构
  [root@controller001 home]# cat sqlalchemy_tur.py
  import sqlalchemy
  from sqlalchemy import create_engine # operate database

  from sqlalchemy.ext.declarative import declarative_base # create database table base>  from sqlalchemy import Column, Integer, String # table structure type
  from sqlalchemy.orm import sessionmaker # Use Database Transaction
  # sqlite database is mostly used for android system.
  # echo=True optios: print the real sql,mostly used in debug.
  engine = create_engine('sqlite:///foo.db', echo=True)   # 创建数据库的引擎
  # 如果是mysql engine,就要先创建database
  [root@controller001 home]# cat sqlalchemy_tur_3.py
  import sqlalchemy
  from sqlalchemy import create_engine
  from sqlalchemy_utils import database_exists, create_database # 需要安装sqlalchemy_utils
  engine = create_engine('mysql://root:dbroot@localhost/sqlalchemy')
  if not database_exists(engine.url):
  create_database(engine.url)
  print(database_exists(engine.url))
  # 不同数据库的engine配置:http://sqlalchemy.readthedocs.org/en/rel_1_0/core/engines.html
  Base = declarative_base()
  class User(Base):
  __tablename__ = 'users'
  id = Column(Integer, primary_key=True)
  name = Column(String)
  fullname = Column(String)
  password = Column(String)
  def __repr__(self):
  return "<User(name='%s', fullname='%s', password='%s')>" %(
  self.name, self.fullname, self.password)
  Base.metadata.create_all(engine)
  执行后,会在本地生成一个foo.db sqlite数据库
  插入数据
  user_1 = User(name='user1', fullname='Yao', password='user1')
  Session = sessionmaker(bind=engine)    # 使用数据库事务,保持数据原子性
  session = Session()
  session.add(user_1)
  session.commit()
# 执行结果  
[root@controller001 home]# python sqlalchemy_tur.py
  
2015-09-13 20:59:16,178 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1
  
2015-09-13 20:59:16,179 INFO sqlalchemy.engine.base.Engine ()
  
2015-09-13 20:59:16,179 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1
  
2015-09-13 20:59:16,179 INFO sqlalchemy.engine.base.Engine ()
  
2015-09-13 20:59:16,181 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
  
2015-09-13 20:59:16,182 INFO sqlalchemy.engine.base.Engine INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
  
2015-09-13 20:59:16,182 INFO sqlalchemy.engine.base.Engine ('user1', 'Yao', 'user1')
  
2015-09-13 20:59:16,184 INFO sqlalchemy.engine.base.Engine SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password
  
FROM users
  
WHERE users.name = ?
  
LIMIT ? OFFSET ?
  
2015-09-13 20:59:16,185 INFO sqlalchemy.engine.base.Engine ('user1', 1, 0)
  
2015-09-13 20:59:16,186 INFO sqlalchemy.engine.base.Engine COMMIT
  
[root@controller001 home]# sqlite3 foo.db
  
SQLite version 3.7.17 2013-05-20 00:56:22
  
Enter ".help" for instructions
  
Enter SQL statements terminated with a ";"
  
sqlite> select * from users;
  
1|user1|Yao|user1
  插入多条数据
  Session = sessionmaker(bind=engine)
  session = Session()
  session.add_all([
  User(name='user1', fullname='user1_1', password='123'),
  User(name='user2', fullname='user2_2', password='123'),
  User(name='user3', fullname='user3_3', password='123')])
  session.commit()
# 执行结果  
root@controller001 home]# python sqlalchemy_tur.py
  
2015-09-13 21:08:25,372 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1
  
2015-09-13 21:08:25,372 INFO sqlalchemy.engine.base.Engine ()
  
2015-09-13 21:08:25,373 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1
  
2015-09-13 21:08:25,373 INFO sqlalchemy.engine.base.Engine ()
  
2015-09-13 21:08:25,374 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
  
2015-09-13 21:08:25,376 INFO sqlalchemy.engine.base.Engine INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
  
2015-09-13 21:08:25,376 INFO sqlalchemy.engine.base.Engine ('user1', 'user1_1', '123')
  
2015-09-13 21:08:25,377 INFO sqlalchemy.engine.base.Engine INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
  
2015-09-13 21:08:25,377 INFO sqlalchemy.engine.base.Engine ('user2', 'user2_2', '123')
  
2015-09-13 21:08:25,377 INFO sqlalchemy.engine.base.Engine INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
  
2015-09-13 21:08:25,378 INFO sqlalchemy.engine.base.Engine ('user3', 'user3_3', '123')
  
2015-09-13 21:08:25,380 INFO sqlalchemy.engine.base.Engine SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password
  
FROM users
  
WHERE users.name = ?
  
LIMIT ? OFFSET ?
  
2015-09-13 21:08:25,380 INFO sqlalchemy.engine.base.Engine ('user1', 1, 0)
  
2015-09-13 21:08:25,381 INFO sqlalchemy.engine.base.Engine COMMIT
  
[root@controller001 home]# sqlite3 foo.db
  
SQLite version 3.7.17 2013-05-20 00:56:22
  
Enter ".help" for instructions
  
Enter SQL statements terminated with a ";"
  
sqlite> select * from users;
  
1|user1|Yao|user1
  
2|user1|user1_1|123
  
3|user2|user2_2|123
  
4|user3|user3_3|123
  查询
  res = session.query(User).filter_by(name='user1').first()
  res = session.query(User).all() # 全表扫描

  for row in session.query(User).order_by(User.id): #>  print row
  for row in session.query(User).filter(User.name.in_(['yao','shen','tim'])):  # in操作
  print row
  for row in session.query(User).filter(~User.name.in_(['yao','shen','tim'])): # not in 操作
  print row
  session.query(User).filter(User.name == 'yao').count()  # 计数操作
  from sqlalchemy import and_, or_
  for row in session.query(User).filter(and_(User.name == 'yao', User.fullname=='yao')): # 与操作
  print row
  for row in session.query(User).filter(or_(User.name == 'yao', User.fullname=='yao')): # 或操作
  print row
  
  创建一个带有外键的表
  [root@controller001 home]# cat sqlalchemy_tur.py
  import sqlalchemy
  from sqlalchemy import create_engine # operate database

  from sqlalchemy.ext.declarative import declarative_base # create database table base>  from sqlalchemy import Column, Integer, String # table structure type
  from sqlalchemy.orm import sessionmaker # Use Database Transaction
  # sqlite database is mostly used for android system.
  # echo=True optios: print the real sql,mostly used in debug.
  engine = create_engine('sqlite:///foo.db', echo=True)
  Base = declarative_base()
  class User(Base):
  __tablename__ = 'users'
  id = Column(Integer, primary_key=True)
  name = Column(String)
  fullname = Column(String)
  password = Column(String)
  def __repr__(self):
  return "<User(name='%s', fullname='%s', password='%s')>" %(
  self.name, self.fullname, self.password)
  from sqlalchemy import ForeignKey

  from sqlalchemy.orm import>  class Address(Base):
  __tablename__ = 'address'
  id = Column(Integer, primary_key=True)
  email_address = Column(String, nullable=False)
  user_id = Column(Integer, ForeignKey('users.id'))

  user =>  def __repr__(self):
  return "<Address(email_address='%s')" % self.email_address
  Base.metadata.create_all(engine)
# 执行结果  
[root@controller001 home]# python sqlalchemy_tur.py
  
2015-09-13 21:31:37,289 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1
  
2015-09-13 21:31:37,289 INFO sqlalchemy.engine.base.Engine ()
  
2015-09-13 21:31:37,290 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1
  
2015-09-13 21:31:37,290 INFO sqlalchemy.engine.base.Engine ()
  
2015-09-13 21:31:37,291 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("users")
  
2015-09-13 21:31:37,292 INFO sqlalchemy.engine.base.Engine ()
  
2015-09-13 21:31:37,292 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("address")
  
2015-09-13 21:31:37,293 INFO sqlalchemy.engine.base.Engine ()
  
2015-09-13 21:31:37,293 INFO sqlalchemy.engine.base.Engine
  
CREATE TABLE address (
  
id INTEGER NOT NULL,
  
email_address VARCHAR NOT NULL,
  
user_id INTEGER,
  
PRIMARY KEY (id),
  
FOREIGN KEY(user_id) REFERENCES users (id)
  
)
  
2015-09-13 21:31:37,293 INFO sqlalchemy.engine.base.Engine ()
  
2015-09-13 21:31:37,343 INFO sqlalchemy.engine.base.Engine COMMIT
  插入数据
  ice = User(name='ice', fullname='ice yao', password='ice')
  ice.addresses = [
  Address(email_address='ice@gg.com'),
  Address(email_address='yao@gg.com')
  ]
  session.add(ice)
  session.commit()
  for u, a in session.query(User, Address).\
  filter(User.id==Address.user_id).\
  filter(Address.email_address=='ice@gg.com').\
  all():
  print u, a
  SQLAlchemy Core详解
  
  创建数据库及表
  [root@controller001 home]# cat sqlalchemy_tur_2.py
  import sqlalchemy
  from sqlalchemy import create_engine
  from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
  engine = create_engine('sqlite:///foo.db', echo=True)
  metadata = MetaData()
  users = Table('users', metadata,         # 这里使用Table来创建表
  Column('id', Integer, primary_key=True),
  Column('name', String),
  Column('fullname', String)
  )
  address = Table('address', metadata,
  Column('id', Integer, primary_key=True),
  Column('user_id', None, ForeignKey('users.id')),
  Column('email_address', String, nullable=False)
  )
  metadata.create_all(engine)
  
  查看sqlite数据库
  
  sqlite> .schema
  CREATE TABLE users (
  id INTEGER NOT NULL,
  name VARCHAR,
  fullname VARCHAR,
  PRIMARY KEY (id)
  );
  CREATE TABLE address (
  id INTEGER NOT NULL,
  user_id INTEGER,
  email_address VARCHAR NOT NULL,
  PRIMARY KEY (id),
  FOREIGN KEY(user_id) REFERENCES users (id)
  );
  插入数据
conn = engine.connect()   # 初始化一个连接  
conn.execute(users.insert(), [dict(name='jack', fullname='jack jons'),
  
dict(name='wendy', fullname='wendy ice')])
  
  查询
  from sqlalchemy.sql import select
  s = select([users])    # 语法很像sql
  res = conn.execute(s)
  for row in res:
  print row
# 执行结果  
[root@controller001 home]# python sqlalchemy_tur_2.py
  
2015-09-13 22:24:14,459 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1
  
2015-09-13 22:24:14,460 INFO sqlalchemy.engine.base.Engine ()
  
2015-09-13 22:24:14,460 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1
  
2015-09-13 22:24:14,460 INFO sqlalchemy.engine.base.Engine ()
  
2015-09-13 22:24:14,462 INFO sqlalchemy.engine.base.Engine SELECT users.id, users.name, users.fullname
  
FROM users
  
2015-09-13 22:24:14,462 INFO sqlalchemy.engine.base.Engine ()
  
(1, u'jack', u'jack jons')
  
(2, u'wendy', u'wendy ice')
  # 带where的条件查询
  from sqlalchemy.sql import select
  s = select([users, address]).where(users.c.id == address.c.user_id)
  res = conn.execute(s)
  for row in res:
  print row
  # 使用text,更像sql了
  from sqlalchemy.sql import select
  s = text(

  "SELECT users.fullname || ',' || address.email_address AS>  "FROM users, address "
  "WHERE users.id = address.user_id "
  "AND users.name BETWEEN :x AND :y "
  "AND (address.email_address LIKE :t1 "
  "OR address.email_address LIKE :t2)")
  res = conn.execute(s, x='m',y='z',t1='@yao.com',t2='@ice.com').fetchall()
  for row in res:
  print row

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-550246-1-1.html 上篇帖子: Python脚本之TCP端口检查 下篇帖子: CentOS6.8安装python2.7.12以及ipython教程
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表