1. 程式人生 > >python資料庫操作之pymysql模組和sqlalchemy模組(專案必備)

python資料庫操作之pymysql模組和sqlalchemy模組(專案必備)

pymysql

 pymsql是Python中操作MySQL的模組,其使用方法和MySQLdb幾乎相同。

1、下載安裝

pip3 install pymysql

2、操作資料庫

(1)、執行sql

複製程式碼
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pymysql
  
# 建立連線
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1')
# 建立遊標
cursor = conn.cursor()
  
# 執行SQL,並返回收影響行數
effect_row 
= cursor.execute("update hosts set host = '1.1.1.2'") # 執行SQL,並返回受影響行數 #effect_row = cursor.execute("update hosts set host = '1.1.1.2' where nid > %s", (1,)) # 執行SQL,並返回受影響行數 #effect_row = cursor.executemany("insert into hosts(host,color_id)values(%s,%s)", [("1.1.1.11",1),("1.1.1.11",2)]) # 提交,不然無法儲存新建或者修改的資料 conn.commit() # 關閉遊標 cursor.close() # 關閉連線 conn.close()
複製程式碼

(2)、獲取新建立資料自增ID

複製程式碼
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pymysql
  
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1')
cursor = conn.cursor()
cursor.executemany("insert into hosts(host,color_id)values(%s,%s)", [("1.1.1.11",1),("1.1.1.11",2)])
conn.commit()
cursor.close()
conn.close()
  
# 獲取最新自增ID
new_id 
= cursor.lastrowid
複製程式碼

(3)、獲取查詢資料

複製程式碼
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pymysql
  
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1')
cursor = conn.cursor()
cursor.execute("select * from hosts")
  
# 獲取第一行資料
row_1 = cursor.fetchone()
  
# 獲取前n行資料
# row_2 = cursor.fetchmany(3)
# 獲取所有資料
# row_3 = cursor.fetchall()
  
conn.commit()
cursor.close()
conn.close()
複製程式碼

注:在fetch資料時按照順序進行,可以使用cursor.scroll(num,mode)來移動遊標位置,如:

  • cursor.scroll(1,mode='relative')  # 相對當前位置移動
  • cursor.scroll(2,mode='absolute') # 相對絕對位置移動

(4)、fetch資料型別

  關於預設獲取的資料是元祖型別,如果想要或者字典型別的資料,即:

複製程式碼
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pymysql
  
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1')
  
# 遊標設定為字典型別
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
r = cursor.execute("call p1()")
  
result = cursor.fetchone()
  
conn.commit()
cursor.close()
conn.close()
複製程式碼

sqlalchemy簡介

SQLAlchemy是Python程式語言下的一款開源軟體。提供了SQL工具包及物件關係對映(ORM)工具,使用MIT許可證發行。

SQLAlchemy“採用簡單的Python語言,為高效和高效能的資料庫訪問設計,實現了完整的企業級持久模型”。SQLAlchemy的理念是,SQL資料庫的量級和效能重要於物件集合;而物件集合的抽象又重要於表和行。因此,SQLAlchmey採用了類似於JavaHibernate的資料對映模型,而不是其他ORM框架採用的Active Record模型。不過,Elixir和declarative等可選外掛可以讓使用者使用宣告語法。

SQLAlchemy與資料庫關係圖如下:

sqlalchemy基本操作

一、安裝sqlalchemy

  • 本文采用的是mysql案例,所以需要一臺有安裝mysql資料庫的機器
  • 使用python的pip3安裝 pip3 install sqlalchemy

安裝完後檢視版本資訊

import sqlalchemy
sqlalchemy.__version__

二、連線資料庫

在sqlalchemy中,session用於建立程式與資料庫之間的會話。所有物件的載入和儲存都需要通過session物件。

複製程式碼
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

# 連結資料庫採用pymysq模組做對映,後面引數是最大連線數5
ENGINE=create_engine("mysql+pymysql://[email protected]:3306/digchouti?charset=utf8", max_overflow=5)
Session = sessionmaker(bind=engine)

session = Session()
複製程式碼

三、建立對映(建立表)

一個對映對應著一個Python類,用來表示一個表的結構。下面建立一個person表,包括id和name兩個欄位。也就是說建立表就是用python的的類來實現

複製程式碼
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://[email protected]:3306/digchouti?charset=utf8", max_overflow=5)

#生成一個SQLORM基類,建立表必須繼承他,別問我啥意思就是這麼規定的
Base = declarative_base()

class Person(Base):
    __tablename__ = 'userinfo'

    id   = Column(Integer, primary_key=True)
    name = Column(String(32))

    def __repr__(self):
        return "<Person(name='%s')>" % self.name
複製程式碼

此程式碼是建立了一個名字叫userinfo的表,表裡有兩列,一列是id,一列是name。

四、新增資料

當然我們建立了表,肯定也要新增資料,程式碼如下:

複製程式碼
#建立一個person物件
person = Person(name='張巖林')
#新增person物件,但是仍然沒有提交到資料庫
session.add(person)
#提交資料庫
session.commit()
複製程式碼

當然還能新增多條資料:

session.add_all([
    Person(name='張巖林'),
    Person(name='aylin')
])
session.commit()

五、查詢資料

在sqlalchemy模組中,查詢資料給提供了query()的方法 下面我就把能用到的給列舉一下:

複製程式碼
#獲取所有資料
session.query(Person).all()

#獲取name=‘張巖林’的那行資料
session.query(Person).filter(Person.name=='張巖林').one()

#獲取返回資料的第一行
session.query(Person).first()

#查詢id大於1的所有資料
session.query(Person.name).filter(Person.id>1).all()

#limit索引取出第一二行資料
session.query(Person).all()[1:3]

#order by,按照id從大到小排列
session.query(Person).ordre_by(Person.id)

#equal/like/in
query = session.query(Person)
query.filter(Person.id==1).all()
query.filter(Person.id!=1).all()
query.filter(Person.name.like('%ay%')).all()
query.filter(Person.id.in_([1,2,3])).all()
query.filter(~Person.id.in_([1,2,3])).all()
query.filter(Person.name==None).all()

#and or
from sqlalchemy import and_
from sqlalchemy import or_
query.filter(and_(Person.id==1, Person.name=='張巖林')).all()
query.filter(Person.id==1, Person.name=='張巖林').all()
query.filter(Person.id==1).filter(Person.name=='張巖林').all()
query.filter(or_(Person.id==1, Person.id==2)).all()

# count計算個數
session.query(Person).count()

# 修改update
session.query(Person).filter(id > 2).update({'name' : '張巖林'})
複製程式碼 複製程式碼
# 萬用字元
ret = session.query(Users).filter(Users.name.like('e%')).all()
ret = session.query(Users).filter(~Users.name.like('e%')).all()

# 限制
ret = session.query(Users)[1:2]

# 排序
ret = session.query(Users).order_by(Users.name.desc()).all()
ret = session.query(Users).order_by(Users.name.desc(), Users.id.asc()).all()

# 分組
from sqlalchemy.sql import func

ret = session.query(Users).group_by(Users.extra).all()
ret = session.query(
    func.max(Users.id),
    func.sum(Users.id),
    func.min(Users.id)).group_by(Users.name).all()

ret = session.query(
    func.max(Users.id),
    func.sum(Users.id),
    func.min(Users.id)).group_by(Users.name).having(func.min(Users.id) >2).all()

# 連表

ret = session.query(Users, Favor).filter(Users.id == Favor.nid).all()

ret = session.query(Person).join(Favor).all()

ret = session.query(Person).join(Favor, isouter=True).all()


# 組合
q1 = session.query(Users.name).filter(Users.id > 2)
q2 = session.query(Favor.caption).filter(Favor.nid < 2)
ret = q1.union(q2).all()

q1 = session.query(Users.name).filter(Users.id > 2)
q2 = session.query(Favor.caption).filter(Favor.nid < 2)
ret = q1.union_all(q2).all()
複製程式碼

查詢這塊比較多,可能寫的不全還望各位見諒,剩下我相信大家都能擴充套件起來

上面的介紹完了,可能各位還不能吧融合到一塊去,下面我給大家融合寫在一塊吧:

複製程式碼
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column
from sqlalchemy import Integer, String, TIMESTAMP
from sqlalchemy import ForeignKey, UniqueConstraint, Index
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy import create_engine

ENGINE=create_engine("mysql+pymysql://[email protected]:3306/digchouti?charset=utf8", max_overflow=5)

Base = declarative_base()

class Person(Base):
    __tablename__ = 'userinfo'

    id   = Column(Integer, primary_key=True)
    name = Column(String(32))

    def __repr__(self):
        return "<Person(name='%s')>" % self.name

#建立連線資料庫以供提交用,至此表會建立完成,可以去資料庫裡面檢視
Base.metadata.create_all(ENGINE)
Session = sessionmaker(bind=engine)
# 往裡面插入多條資料
session = Session()
session.add_all([
    Person(name='張巖林'),
    Person(name='很帥')
])
session.commit()
複製程式碼

sqlalchemy表關係之高階用法

上面闡述的是對於一張表的操作,下面將說的是表關係的一對多,多對多,瞭解資料庫的都知道外來鍵,也就是表關係建立。

1、一對多外來鍵(1)

第一種方法我們只用到普通的操作,這個方式相對於好理解,在第一張表建立完,插入資料然後要記得提交資料,然後往第二章表建立資料的時候,可以直接拿第一張相關聯的資料,程式碼如下:

複製程式碼
#!/usr/bin/env python
# -*- coding:utf-8 -*-

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import  Column,Integer,ForeignKey,UniqueConstraint,Index,String
from sqlalchemy.orm import sessionmaker,relationship
from sqlalchemy import create_engine


engine=create_engine('mysql+pymysql://[email protected]:3306/db1')

Base = declarative_base()

class Son(Base):
    __tablename__ = 'son'
    id = Column(Integer,primary_key=True)
    name = Column(String(32))
    age = Column(String(32))
    # 建立外來鍵,對應父親那張表的id項
    father_id = Column(Integer,ForeignKey('father.id'))

class Father(Base):
    __tablename__ = 'father'
    id = Column(Integer,primary_key=True)
    name = Column(String(32))
    age = Column(String(32))

Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()

f1 = Father(name = 'zhangyanlin',age = '18')
session.add(f1)
session.commit()

w1 = Son(name = 'xiaozhang1',age = 3,father_id = 1)
w2 = Son(name = 'xiaozhang2',age = 3,father_id = 1)

session.add_all([w1,w2])
session.commit()
複製程式碼

2、一對多外來鍵(2)relationship

 第二種方法和第一種一樣,只是這裡改用了relationship來做外來鍵關係,程式碼如下:

複製程式碼
#!/usr/bin/env python
# -*- coding:utf-8 -*-

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import  Column,Integer,ForeignKey,UniqueConstraint,Index,String
from sqlalchemy.orm import sessionmaker,relationship
from sqlalchemy import create_engine


engine = create_engine('mysql+pymysql://[email protected]:3306/db1')

Base = declarative_base()

class Son(Base):
    __tablename__ = 'son'
    id = Column(Integer,primary_key=True)
    name = Column(String(32))
    age = Column(String(32))

    father_id = Column(Integer,ForeignKey('father.id'))

class Father(Base):
    __tablename__ = 'father'
    id = Column(Integer,primary_key=True)
    name = Column(String(32))
    age = Column(String(32))
    son = relationship('Son')

Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()

f1 = Father(name = 'zhangyanlin',age = '18')

w1 = Son(name = 'xiaozhang1',age = '3')
w2 = Son(name = 'xiaozhang2',age = '4')
# 重點是這裡繫結關係
f1.son = [w1,w2]
# 只需要把父親給傳進去,兒子的自然就上傳進去啦
session.add(f1)
session.commit()