SQLalchemy基礎



1、ORM 概述
  • ORM 框架:
    • orm:關係對象映射,
    • DBAPI:
      • SQLAlchemy只是將類、對象轉換爲sql語句,交由DBAPI去執行
      • 一大堆模塊集合,包含pymysql, mysqldb即各類數據庫client端api插件
    • Dialect:
      • 鏈接數據庫的配置文件,記錄了鏈接db要使用的api模塊,db主機名、
    • ConnectionPooling:
      • 數據庫鏈接池
    • Engine:
      • orm核心

  • 鏈接方式:
    • SQLAlchemy 自己沒法連接數據庫,是其中的Dialect使用第三方插件(pymysql等)而調用不一樣數據庫的API來實現數據庫操做
  • 利用各類底層模塊的鏈接方式:
# MySQL-Python
mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
# pymysql
mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
# MySQL-Connector
mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname>
# cx_Oracle
oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...]
 

補充 :數據類型
from sqlalchemy.dialects.mysql import \         BIGINT, BINARY, BIT, BLOB, BOOLEAN, CHAR, DATE, \         DATETIME, DECIMAL, DECIMAL, DOUBLE, ENUM, FLOAT, INTEGER, \         LONGBLOB, LONGTEXT, MEDIUMBLOB, MEDIUMINT, MEDIUMTEXT, NCHAR, \         NUMERIC, NVARCHAR, REAL, SET, SMALLINT, TEXT, TIME, TIMESTAMP, \         TINYBLOB, TINYINT, TINYTEXT, VARBINARY, VARCHAR, YEAR




2、基本及操做
    • 安裝:
      • pymyql 、sqlalchemy 模塊
    • 導入的模塊
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import sessionmaker
    • 建立連接
engine = create_engine("mysql+pymysql://root:redhat@192.168.10.202/db01?charset=utf8", echo=True)
# echo 表示是否將執行過程生成的語句打印出來; charset 要在?後面寫,能夠輸入中文,外面寫不行
    • 建立表結構
Base = declarative_base() # 聲明基礎類

class User(Base):
    __tablename__ = 'user' # 表名稱
    id = Column(Integer, primary_key=True)
    u_id = Column(Integer, nullable=False)
    u_name = Column(String(32), nullable=False)
    u_pass = Column(String(32), nullable=False)

# Base.metadata.create_all(engine)
# Base.metadata.drop_all(engine)
注意:屢次執行,不會重複建立,若DB中有該表,那麼只是將該表的「表結構」映射給 class;(對錶的操做,必須有該表的表結構)
    • 插入數據:
Session_cls = sessionmaker(bind=engine)  #建立與數據庫的會話session class ,注意,這裏返回給session的是個class,不是實例
Session = Session_cls()  #生成session實例

# 聲明要建立的數據對象,並添加到session中,此時沒有進行建立
obj = User(name='user1', age=18, favo='black')  # 增長單條數據
session.add_all([
     User(name='user2', age=20, favo='green'),
     User(name='user3', age=30, favo='blue')
 ])  ## 增長多條數據,[obj1, obj2, obj3]
Session.commit()  ## 提交修改,此時纔是真正的建立數據

## 批量建立
for i in range(10):
    user_obj = User(u_id=i, u_name='user-' + str(i), u_pass='passwd-' + str(i))
    Session.add(user_obj)
Session.commit()



3、查詢中的注意問題
    • 注意問題:
      • query(類名),查詢的結果爲對象,每一個對象對應表中的一行條目,經過obj.字段 來獲取該條目相應字段的值
      • all(),講全部查詢到的對象放在一個列表中
      • first(),只取回對象列表中的第一個對象
      • __repr__()方法,
        • 默認狀況下,沒有該方法時,print(獲取到的對象),則獲得的是對象的內存地址
        • 如有該方法,則print(獲取到的對象),則顯示的是該方法的返回值,更加人性化的區別開了各個對象(條目)
class User(Base):
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True)
    u_id = Column(Integer, nullable=False)
    u_name = Column(String(32), nullable=False)
    u_pass = Column(String(32), nullable=False)

    def __repr__(self):
        obj_desc = '<id:{}, name:{}, passwd:{}>'.format(self.u_id, self.u_name, self.u_pass)
        return obj_desc


Session_cls = sessionmaker(bind=engine)
Session = Session_cls()

obj_lst = Session.query(User).filter(User.u_name == 'user-1').all()
obj_first = Session.query(User).filter(User.u_name == 'user-1').first()
print(obj_lst)
print(obj_first.name) # 獲取該對象的u_name字段值
# 沒有__repr__方法:[<__main__.User object at 0x0000000003EAA8D0>]  print獲得的是內存地址
# 有__repr__方法: [<id:1, name:user-1, passwd:passwd-1>]  print獲得該方法返回值
    • 多條件查詢:
obj_lst = Session.query(User).filter(User.id > 3).filter(User.u_id < 5).all()
for obj in obj_lst:
    print(obj.u_name)
  • 數據修改
#### 對象賦值方式
obj = Session.query(User).filter(User.id > 3).filter(User.u_id < 5).first()
obj.u_name = 'qiaogy'  # 修改便是對該對象字段從新賦值
Session.commit()
#### sql語句方式
Session.query(User).filter(User.u_name == 'user-1').update({User.u_name: 'est'}, synchronize_session=False)
Session.query(User).filter(User.u_name == '關羽').update({User.u_id: User.u_id - 100}, synchronize_session="evaluate")
Session.commit()
evaluate:默認值,會同時修改當前session會話中的對象屬性;False 表示不修改當前會話中的對象屬性
  • 刪除數據
Session.query(User).filter(User.u_id > 20).delete()
Session.commit()
  • 數據回滾
fake_user = User(u_id=10, u_name='Rain', u_pass='12345')
Session.add(fake_user)
print(Session.query(User).filter(User.u_name.in_(['Jack', 'rain'])).all())  # 這時看session裏有你剛添加和修改的數據
Session.rollback()
print(Session.query(User).filter(User.u_name.in_(['Jack', 'rain'])).all())  # 再查就發現剛纔添加的數據沒有了。
# 沒有什麼暖用,由於不提交,照樣不會生效,一提交,回滾也救不了
  • 統計
from sqlalchemy import func
ret = Session.query(User).filter(User.u_id > 9).count()
print(ret)
  • 分組:
from sqlalchemy import func
ret = Session.query(User.u_name, func.count(User.u_name)).group_by(User.u_name).all()
print(ret)



4、補充 查詢問題:
  • 映射:query(table.cloumn)
obj_lst = Session.query(User.u_name, User.u_pass).filter(User.u_id > 5).all()
print(obj_lst)
## 查詢結果爲:[('user-6', 'passwd-6'), ('user-7', 'passwd-7'), ('user-8', 'passwd-8')], 每一個對象的各個字段被組織成元組
  • 過濾
## filter
obj = Session.query(User).filter(User.id == 3).first()  # 條件爲表達式格式,可使用 > < 來表示範圍,不能走索引
obj = Session.query(User).filter_by(id=3).first()  # 條件爲K=V格式,不能取範圍,可是能夠走索引

## filter 範圍之 in_, between
obj_lst = Session.query(User.u_name).filter(User.id.between(3,5)).all()    # 範圍爲前閉後閉
obj_lst = Session.query(User.u_name).filter(~User.id.between(3,5)).all() # 取反
obj_lst = Session.query(User.u_name).filter(User.id.in_([3,4,6])).all()        # 值在指定列表中的一個
obj_lst = Session.query(User.u_name).filter(~User.id.in_([3,4,6])).all()      # 取反
  • 邏輯之 and 、or
from sqlalchemy import or_, and_
ret = Session.query(User).filter(and_(User.id > 3, User.u_name == 'user-8')).all()
ret = session.query(User).filter(
    or_(User.id > 1# 或者id大於1
        and_(User.name == 'user3', User.id < 4),  # 或者名稱爲user3 且id小於4
        User.favo == 'blue'# 或者顏色爲藍色
    )
).all()
  • 通配符 %多個字符,_單個字符
ret = Session.query(User).filter(User.u_name.like('qiaog_')).all()
ret = Session.query(User.u_name).filter(User.u_name.like('user%')).all()
print(ret)
  • 排序、限制:
ret = Session.query(User).order_by(User.u_id.desc()).all()
ret2 = Session.query(User).order_by(User.u_id.desc()).all()[1:3]































注意:
        sqlalchemy建立的表不能修改表結構,只能從新建立

unique 惟一約束:即該字段值不能重複





做業:
        一、利用rabbitmq實現rpc
        二、SQLAchemy+paramiko 主機管理
                最少2個表:
                        主機表,業務類型,驗證

                mysql保存主機對應關係
                sqlachmy獲取或設置數據
相關文章
相關標籤/搜索