Python SQLAlchemy

SQLAlchemyhtml

 

SQLAlchemy是Python編程語言下的一款ORM框架,該框架創建在數據庫API之上,使用關係對象映射進行數據庫操做,簡言之即是:將對象轉換成SQL,而後使用數據API執行SQL並獲取執行結果。python

對象映射關係(ORM)mysql

orm英文全稱object relational mapping,就是對象映射關係程序,簡單來講咱們相似python這種面向對象的程序來講一切皆對象,可是咱們使用的數據庫卻都是關係型的,爲了保證一致的使用習慣,經過orm將編程語言的對象模型和數據庫的關係模型創建映射關係,這樣咱們在使用編程語言對數據庫進行操做的時候能夠直接使用編程語言的對象模型進行操做就能夠了,而不用直接使用sql語言linux

優勢:sql

  • 隱藏了數據訪問細節,「封閉」的通用數據庫交互,ORM的核心。他使得咱們的通用數據庫交互變得簡單易行,而且徹底不用考慮該死的SQL語句。快速開發,由此而來
  • ORM使咱們構造固化數據結構變得簡單易行

缺點:數據庫

  • 無可避免的,自動化意味着映射和關聯管理,代價是犧牲性能(早期,這是全部不喜歡ORM人的共同點)。如今的各類ORM框架都在嘗試使用各類方法來減輕這塊(LazyLoad,Cache),效果仍是很顯著

 

sqlalchemy安裝編程

Dialect用於和數據API進行交流,根據配置文件的不一樣調用不一樣的數據庫API,從而實現對數據庫的操做,如:session

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...]
 
更多詳見:http://docs.sqlalchemy.org/en/latest/dialects/index.html

注:支持鏈接MySQL、Oracles數據庫數據結構

 

安裝:oracle

pip install SQLAlchemy
pip install pymysql 
#因爲mysqldb依然不支持py3,因此這裏咱們用pymysql與sqlalchemy交互

基本使用

建立表結構

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

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@192.168.91.92/sxl", encoding="utf-8", echo=True)  # echo=True 打印程序運行詳細信息

Base = declarative_base()  # 生成orm基類


class User(Base):
    __tablename__ = "user"  # 表名
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    password = Column(String(64))

class color(Base):
    __tablename__ = "color"  # 表名
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    password = Column(String(64))


Base.metadata.create_all(engine)

 建立數據

最基本的表咱們建立好了,那咱們開始用orm建立一條數據試試

from sqlalchemy import  create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import String,Integer,Column
from sqlalchemy.orm import sessionmaker
 
engine = create_engine("mysql+pymysql://root@192.168.91.92/sxl",
                       encoding="utf-8")
 
Base = declarative_base()   #生成orm基類
 
class User(Base):
    __tablename__ = "user"      #表名
    id = Column(Integer,primary_key=True)
    name = Column(String(32))
    password = Column(String(64))
 
#Base.metadata.create_all(engine)    #建立表結構
 
Session_class = sessionmaker(bind=engine)   #Session_class如今不是實例,而是類
Session = Session_class()   #生成Session實例
 
user_obj = User(name="sxl",password="123")   #生成你要建立的數據對象
print(user_obj.name,user_obj.id)  #此時還沒建立對象呢,不信你打印一下id發現仍是None
 
Session.add(user_obj) #把要建立的數據對象添加到這個session裏, 一會統一建立
print(user_obj.name,user_obj.id) #此時也依然還沒建立
 
Session.commit()    #現此才統一提交,建立數據

 增刪改

from sqlalchemy import  create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import String,Integer,Column
from sqlalchemy.orm import sessionmaker
 
engine = create_engine("mysql+pymysql://root@192.168.91.92/sxl",
                       encoding="utf-8")
 
Base = declarative_base()   #生成orm基類
 
class User(Base):
    __tablename__ = "user"      #表名
    id = Column(Integer,primary_key=True)
    name = Column(String(32))
    password = Column(String(64))
 
#Base.metadata.create_all(engine)    #建立表結構
 
Session_class = sessionmaker(bind=engine)   #Session_class如今不是實例,而是類
Session = Session_class()   #生成Session實例
 
#添加數據 user_obj
= User(name="sxl",password="123") #生成你要建立的數據對象 Session.add(user_obj) #把要建立的數據對象添加到這個session裏, 一會統一建立 Session.commit() #現此才統一提交,建立數據


#查詢數據
myuser=Session.query(user).filter(user.password=='123').first()
print(myuser) #myuser如今是一個對象
print(myuser.id,myuser.name,myuser.password)

#修改數據
myuser.name='abc'
Session.commit()

#刪除數據
Session.delete(myuser)
Session.commit()

 回滾

Session.rollback()

獲取全部數據

print(Session.query(myuser.name,myuser.password).all()

多條件查詢

 Session.query(user).filter(user.id>0).filter(user.id<7).all()

統計和分組

Session.query(user).filter(user.name.like("Ra%")).count()

分組

from sqlalchemy import func
print(Session.query(func.count(user.name),user.name).group_by(user.name).all() )

 

外鍵關聯

咱們先建立個study_record表與student進行關聯

 

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import String,Column,Integer,ForeignKey,DATE
from sqlalchemy.orm import sessionmaker,relationship
 
engine = create_engine("mysql+pymysql://root:zyw@123@192.168.0.59/lzl",
                       encoding="utf-8")
 
Base = declarative_base()
 
class Student(Base):
    __tablename__ ="student"
    id = Column(Integer,primary_key=True)
    name = Column(String(32),nullable=False)
    register_date = Column(DATE,nullable=False)
 
    def __repr__(self):
        return "<%s name:%s>"%(self.id,self.name)
 
class StudyRecord(Base):
    __tablename__ = "study_record"
    id = Column(Integer,primary_key=True)
    day = Column(Integer,nullable=False)
    status = Column(String(32),nullable=False)
    stu_id = Column(Integer,ForeignKey("student.id")) #關聯student表裏的id
 
    my_student = relationship("Student",backref="my_study_record") # Student爲關聯的類
def __repr__(self):
        return "<%s name:%s>" % (self.id, self.name)
 
Base.metadata.create_all(engine)
 
Session_class = sessionmaker(bind=engine)
session = Session_class()
 
s1 = Student(name="lzl",register_date="2016-10-26")
s2 = Student(name="alex",register_date="2015-10-26")
s3 = Student(name="eric",register_date="2014-10-26")
s4 = Student(name="rain",register_date="2013-10-26")
 
r1 = StudyRecord(day=1,status="YES",stu_id=1)
r2 = StudyRecord(day=2,status="No",stu_id=1)
r3 = StudyRecord(day=3,status="YES",stu_id=1)
r4 = StudyRecord(day=1,status="YES",stu_id=2)
 
session.add_all([s1,s2,s3,s4,r1,r2,r3,r4])
session.commit()

 

注:my_student = relationship("Student",backref="my_study_record")這個nb,容許你在user表裏經過backref字段反向查出全部它在addresses表裏的關聯項

 

Session_class = sessionmaker(bind=engine)
session = Session_class()
 
stu_obj = session.query(Student).filter(Student.name=="lzl").first()
print(stu_obj)
#<id:1 name:lzl>
 
print(stu_obj.my_study_record)

 

多外鍵關聯

下表中,Customer表有2個字段都關聯了Address表,首先先建立表結構

 

from sqlalchemy import create_engine
from sqlalchemy import Integer,String,Column,ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker,relationship
 
engine = create_engine("mysql+pymysql://root:zyw@123@192.168.20.219/lzl",
                       encoding="utf-8",echo= True)
 
Base =  declarative_base()
 
class Customer(Base):
    __tablename__ = "customer"
    id = Column(Integer,primary_key=True)
    name = Column(String(32))
    billing_address_id = Column(Integer,ForeignKey("address.id"))
    shipping_address_id = Column(Integer, ForeignKey("address.id"))
 
    billing_address = relationship("Address",foreign_keys=[billing_address_id]) #必須寫foreign_keys
    shipping_address = relationship("Address",foreign_keys=[shipping_address_id])
 
class Address(Base):
    __tablename__ = 'address'
    id = Column(Integer, primary_key=True)
    street = Column(String(32))
    city = Column(String(32))
    state = Column(String(32))
 
Base.metadata.create_all(engine)

 

生成數據:

 

Session = sessionmaker(bind=engine)
session = Session()
 
a1 = Address(street="Tiantongyuan",city="ChangPing",state="BJ")
a2 = Address(street="Wudaokou",city="HaiDian",state="BJ")
a3 = Address(street="Yanjiao",city="LangFang",state="HB")
 
session.add_all([a1,a2,a3])
c1 = Customer(name="lzl",billing_address_id=1,shipping_address_id=2)
c2 = Customer(name="Alex",billing_address_id=3,shipping_address_id=3)
 
session.add_all([c1,c2])
 
session.commit()

 

查詢數據:

 

Session = sessionmaker(bind=engine)
session = Session()
 
cus_obj = session.query(Customer).filter_by(name="lzl").first()
print(cus_obj)

 

多對多關聯

如今來設計一個能描述「圖書」與「做者」的關係的表結構,需求是

  1. 一本書能夠有好幾個做者一塊兒出版
  2. 一個做者能夠寫好幾本書

建立表結構:

 

#一本書能夠有多個做者,一個做者又能夠出版多本書
 
 
from sqlalchemy import Table, Column, Integer,String,DATE, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
 
engine = create_engine("mysql+pymysql://root:zyw@123@192.168.20.219/lzl",
                       encoding="utf-8")
 
Base = declarative_base()
 
#建立book_m2m_author表,表不用用戶操做,系統自動維護,自動添加數據
book_m2m_author = Table('book_m2m_author', Base.metadata,
                        Column('book_id',Integer,ForeignKey('books.id')),
                        Column('author_id',Integer,ForeignKey('authors.id')),
                        )
 
class Book(Base):
    __tablename__ = 'books'
    id = Column(Integer,primary_key=True)
    name = Column(String(64))
    pub_date = Column(DATE)
    #關聯Author類,secondary表示經過book_m2m_author表進行查詢關聯數據,backref反向查詢也同樣
    authors = relationship('Author',secondary=book_m2m_author,backref='books')
     
 
    def __repr__(self):
        return self.name
 
class Author(Base):
    __tablename__ = 'authors'
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
 
    def __repr__(self):
        return self.name
 
Base.metadata.create_all(engine)

 

建立表數據: 

 

Session = sessionmaker(bind=engine)
session = Session()
 
b1 = Book(name="learn python with Alex",pub_date="2014-05-02")
b2 = Book(name="learn linux with Alex",pub_date="2015-05-02")
b3 = Book(name="learn go with Alex",pub_date="2016-05-02")
 
a1 = Author(name="Alex")
a2 = Author(name="Jack")
a3 = Author(name="Rain")
 
#關鍵來了,建立關聯關係
b1.authors = [a1,a3]
b3.authors = [a1,a2,a3]
 
session.add_all([b1,b2,b3,a1,a2,a3])
session.commit()

 

查詢:

 

author_obj = session.query(Author).filter_by(name="Alex").first()
print(author_obj,author_obj.books)
 
book_obj = session.query(Book).filter_by(id=2).first()
print(book_obj,book_obj.authors)
 
 
# Alex [learn python with Alex, learn go with Alex]
# learn go with Alex [Alex, Jack, Rain]

 

多對多刪除

刪除數據時不用管boo_m2m_authors , sqlalchemy會自動幫你把對應的數據刪除

經過書刪除做者

 

author_obj =s.query(Author).filter_by(name="Jack").first()
  
book_obj = s.query(Book).filter_by(name="跟Alex學把妹").first()
  
book_obj.authors.remove(author_obj) #從一本書裏刪除一個做者
s.commit()

 

直接刪除做者 

刪除做者時,會把這個做者跟全部書的關聯關係數據也自動刪除

 

author_obj =s.query(Author).filter_by(name="Alex").first()
# print(author_obj.name , author_obj.books)
s.delete(author_obj)
s.commit()
相關文章
相關標籤/搜索