python與數(shù)據(jù)庫的交互-sqlalchemy

導(dǎo)讀:
orm英文全稱object relational mapping,就是對(duì)象映射關(guān)系程序,簡單來說我們類似python這種面向?qū)ο蟮某绦騺碚f一切皆對(duì)象,但是我們使用的數(shù)據(jù)庫卻都是關(guān)系型的,為了保證一致的使用習(xí)慣,通過orm將編程語言的對(duì)象模型和數(shù)據(jù)庫的關(guān)系模型建立映射關(guān)系,這樣我們?cè)谑褂镁幊陶Z言對(duì)數(shù)據(jù)庫進(jìn)行操作的時(shí)候可以直接使用編程語言的對(duì)象模型進(jìn)行操作就可以了,而不用直接使用sql語言。
2.ORM的優(yōu)點(diǎn)和缺點(diǎn)
orm的優(yōu)點(diǎn):
隱藏了數(shù)據(jù)訪問細(xì)節(jié),“封閉”的通用數(shù)據(jù)庫交互,ORM的核心。他使得我們的通用數(shù)據(jù)庫交互變得簡單易行,并且完全不用考慮該死的SQL語句??焖匍_發(fā),由此而來。
ORM使我們構(gòu)造固化數(shù)據(jù)結(jié)構(gòu)變得簡單易行。
缺點(diǎn):
無可避免的,自動(dòng)化意味著映射和關(guān)聯(lián)管理,代價(jià)是犧牲性能(早期,這是所有不喜歡ORM人的共同點(diǎn))。現(xiàn)在的各種ORM框架都在嘗試使用各種方法來減輕這塊(LazyLoad,Cache),效果還是很顯著的。
<在python中最著名的ORM是SQLAlchemy>
------------------------------------------------常用代碼------------------------

from sqlalchemy import Column, String, create_engine,Integer,func ,ForeignKey,DATE,Table
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from  sqlalchemy .orm import  sessionmaker   #創(chuàng)建繪畫
from  sqlalchemy .orm import  relationship   #實(shí)現(xiàn)反向查找

# 初始化數(shù)據(jù)庫連接:
engine = create_engine('mysql+pymysql://root:123456@localhost:3308/szldb?charset=utf8',encoding='utf-8') # echo=True 打印所有信息
# 創(chuàng)建DBSession
DBSession = sessionmaker(bind=engine) 
Base=declarative_base()  #創(chuàng)建基類
Session_class= sessionmaker(bind=engine)  #創(chuàng)建于數(shù)據(jù)庫的會(huì)話sessionclass
Session=Session_class()   #生成session實(shí)例 cursor

(一)數(shù)據(jù)庫的連接
連接mysql
'mysql+pymysql://root:123456@localhost:3308/szldb?charset=utf8',encoding='utf-8',echo=True
連接oracle
oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...]
(數(shù)據(jù)庫類型+基礎(chǔ)包+賬號(hào)+密碼+主機(jī)+端口+編碼方式,字符編碼方式,是否顯示創(chuàng)建細(xì)節(jié))
(一)數(shù)據(jù)庫的連接創(chuàng)建表的結(jié)構(gòu)

from sqlalchemy import  create_engine,Table, String,ForeignKey,Integer,DATE
from sqlalchemy.ext.declarative import declarative_base
#①基本表的創(chuàng)建方式一
engine = create_engine('mysql+pymysql://root:123456@localhost:3308/szldb?charset=utf8',encoding='utf-8') # echo=True 打印所有信息
DBSession = sessionmaker(bind=engine)
Base=declarative_base()  #創(chuàng)建基類
class User(Base):
    __tablename__ = 'user'  # 表名
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    password = Column(String(64))
    def __repr__(self): #返回打印顯示的列
        return "<%s name: %s>" % (self.id,self.name)
#②基本表的創(chuàng)建方式二
from sqlalchemy import Table, MetaData, Column, Integer, String, ForeignKey
from sqlalchemy.orm import mapper
 
metadata = MetaData()
 #設(shè)置表結(jié)構(gòu)
user = Table('user', metadata,
            Column('id', Integer, primary_key=True),
            Column('name', String(50)),
            Column('fullname', String(50)),
            Column('password', String(12))
        )
 #將表的結(jié)構(gòu)轉(zhuǎn)化為類的屬性
class User(object):
    def __init__(self, name, fullname, password):
        self.name = name
        self.fullname = fullname
        self.password = password
mapper(User, user) 

③插入數(shù)據(jù)

Session_class = sessionmaker(bind=engine) #創(chuàng)建與數(shù)據(jù)庫的會(huì)話session class ,注意,這里返回給session的是個(gè)class,不是實(shí)例
Session = Session_class() #生成session實(shí)例

user_obj = User(name="alex",password="alex3714") #生成你要?jiǎng)?chuàng)建的數(shù)據(jù)對(duì)象
#print(user_obj.name,user_obj.id)  #此時(shí)還沒創(chuàng)建對(duì)象呢,不信你打印一下id發(fā)現(xiàn)還是None
 
Session.add(user_obj) #把要?jiǎng)?chuàng)建的數(shù)據(jù)對(duì)象添加到這個(gè)session里, 一會(huì)統(tǒng)一創(chuàng)建
#print(user_obj.name,user_obj.id) #此時(shí)也依然還沒創(chuàng)建
 Session.commit() #現(xiàn)此才統(tǒng)一提交,創(chuàng)建數(shù)據(jù)

④查詢數(shù)據(jù)-基本查詢

data=Session.query(User).filter_by(name='alex').all() #把所有數(shù)據(jù)取成列表
data=Session.query(User).filter_by(name='alex').first() #取首行數(shù)據(jù)
    #條件查詢
data=Session.query(User).filter(User.id==2).all() #條件等于
data=Session.query(User).filter(User.id>2).all() #條件大于
    #多條件查詢
data=Session.query(User).filter(User.id>2).filter(User.id<4).all() #條件大于
data=Session.query(User).filter(User.id>2).filter(User.id<4).first() #
data.name="zhangsan"
data.password="123"
   #統(tǒng)計(jì)和分組
data=Session.query(User).filter(User.name.like("al%")).count() #對(duì)符合條件的記錄進(jìn)行計(jì)數(shù)
print(data)
print(Session.query(func.count(User.name),User.name).group_by(User.name).all() ) #對(duì)數(shù)據(jù)進(jìn)行分組
    #數(shù)據(jù)的修改1
data=Session.query(User).filter(User.id>2).filter(User.id<4).first()
print("change",data) #打印修改后的數(shù)據(jù)
Session.rollback() #回滾操作
print("rollback",data) #打印修改后的數(shù)據(jù)
Session.commit()

⑤查詢數(shù)據(jù)-聯(lián)表查詢

ret=Session.query(User,Student).filter(User.name==Student.name).all()
ret=Session.query(User).join(Student).all()  #兩個(gè)表有外鍵關(guān)聯(lián)的時(shí)候才能采用
print(ret)

⑥外鍵和反向查詢

#創(chuàng)建Student表
class Student(Base):
    __tablename__ = 'Student'  # 表名
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    register_date=Column(DATE,nullable=False)
    def __repr__(self):
        return "<%s age: %s>" % (self.name,self.register_date)
#創(chuàng)建StudyRecord表
class StudyRecord(Base):
    __tablename__ = 'StudyRecord'  # 表名
    id = Column(Integer, primary_key=True)
    day = Column(Integer,nullable=False)
    status = Column(String(64),nullable=False)
    stu_id=Column(Integer,ForeignKey('Student.id'))
    # student=query(Student).filter(Student.id==stu_obj.stuid).first()
    student=relationship("Student",backref="mystudy_record") #這nb允許兩張表相互調(diào)用反向查找,存在于內(nèi)存對(duì)象中
    def __repr__(self):
        return "<day:%s status: %s>" % (self.day,self.status)

⑦數(shù)據(jù)表的一對(duì)多(一個(gè)客戶有不同賬單地址和收貨地址)

class Customer(Base):
    __tablename__ = 'customer'
    id = Column(Integer, primary_key=True)
    name = Column(String(64))
    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])#用不同的關(guān)聯(lián)名稱
    shipping_address = relationship("Address", foreign_keys=[shipping_address_id])#創(chuàng)建的關(guān)系只存在于內(nèi)存對(duì)象不會(huì)寫入數(shù)據(jù)庫
class Address(Base):
    __tablename__ = 'address'
    id = Column(Integer, primary_key=True)
    street = Column(String(64))
    city = Column(String(64))
    state = Column(String(64))
    def __repr__(self):
        return "<street:%s" % (self.street)

⑧多對(duì)多

book_m2m_author = Table('book_m2m_author', Base.metadata,
                        Column('book_id',Integer,ForeignKey('books.id')),
                        Column('author_id',Integer,ForeignKey('authors.id')),
                        )
class Author(Base):
    __tablename__ = 'author'
    id = Column(Integer, primary_key=True)
    name = Column(String(40))
    def __repr__(self):
        return self.name

class Book(Base):
    __tablename__ = 'books'
    id = Column(Integer,primary_key=True)
    name = Column(String(64))
    pub_date = Column(DATE)
    authors = relationship('authors',secondary=book_m2m_author,backref='books') #多對(duì)多,多表關(guān)聯(lián)
    def __repr__(self):
        return self.name
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載,覺得這篇寫 SQLAlchemy Core,寫得非常不錯(cuò)。不過后續(xù)他沒寫SQLAlchemy ORM... ...
    非夢nj閱讀 5,602評(píng)論 1 14
  • pip install sqlalchemy 1.安裝mysqlapt-get install mysql-ser...
    殘風(fēng)疏影閱讀 1,254評(píng)論 0 1
  • MySQL 命令大全 DDL(數(shù)據(jù)定義語句) CREATE TABLE/DATABASE ALTER TABLE/...
    子非初心閱讀 3,707評(píng)論 0 2
  • 雞湯一下。勵(lì)志一下233看日期!
    Mister_閱讀 311評(píng)論 0 1
  • 長大的我游曳到人間 會(huì)遇見一個(gè)吹陶笛的你 你在舟上 我在水底 距離剛好足夠喜歡你 掙不出漁網(wǎng)的凄凄哀鳴 會(huì)喚來一個(gè)...
    小小七閱讀 278評(píng)論 0 5

友情鏈接更多精彩內(nèi)容