2Python全棧之路系列之SQLAchemy

Python全棧之路系列之SQLAlchemy


成都創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比雄縣網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式雄縣網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋雄縣地區(qū)。費(fèi)用合理售后完善,十多年實(shí)體公司更值得信賴。

SQLAlchemy的是Python SQL工具包和對象關(guān)系映射器,讓應(yīng)用程序開發(fā)者的全部功能和SQL的靈活性。

它提供了一套完整的眾所周知的企業(yè)級持久性模式,專為高效率和高性能的數(shù)據(jù)庫訪問,改編成一個簡單的Python化領(lǐng)域語言。


SQLAlchemy的哲學(xué)

SQL數(shù)據(jù)庫的行為不像對象集合的較具規(guī)模和業(yè)績開始關(guān)系; 對象集合表現(xiàn)得不像越抽象開始關(guān)系表和行。 SQLAlchemy的目的是滿足這兩個原則。

SQLAlchemy認(rèn)為數(shù)據(jù)庫是關(guān)系代數(shù)發(fā)動機(jī),而不僅僅是一個表的集合,行可以不僅從表中選擇,但也加入和其他select語句; 任何這些單元可被組合成一個較大的結(jié)構(gòu),SQLAlchemy的表達(dá)式語言基礎(chǔ)上,從它的核心這個概念。

SQLAlchemy是最有名的對象關(guān)系映射器(ORM),提供數(shù)據(jù)映射模式 ,其中類可以在開放式的,多種方式被映射到數(shù)據(jù)庫中的可選組件-允許對象模型和數(shù)據(jù)庫模式中,以開發(fā)干凈地分離從開始方式。

SQLAlchemy的對這些問題的總體思路是大多數(shù)其它SQL/ORM工具,根植于所謂的complimentarity-導(dǎo)向的方式完全不同; 而不是藏起來了SQL和關(guān)系對象的細(xì)節(jié)自動化墻后面,所有的進(jìn)程都充分一系列組合的,透明的工具中暴露出來 。 該庫發(fā)生在自動冗余任務(wù)的工作,而開發(fā)商仍然在數(shù)據(jù)庫中是如何組織和SQL是如何構(gòu)造的控制。

SQLAlchemy的主要目標(biāo)是改變你對數(shù)據(jù)庫和SQL的方式!

SQLAlchemy的使用

數(shù)據(jù)庫的連接

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>

查看版本

>>> import sqlalchemy
>>> sqlalchemy.__version__
'1.0.14'

創(chuàng)建與刪除表

單表創(chuàng)建

#!/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, Index, UniqueConstraint, ForeignKey
from sqlalchemy.orm import sessionmaker

engine = create_engine('mysql+pymysql://root:as@127.0.0.1:3306/tesql?charset=utf8', echo=True)  # echo=True輸出生成的SQL語句

Base = declarative_base()  # 生成一個ORM基類

class UserInfo(Base):
    __tablename__ = 'UserInfo'  # 表名
    """
    創(chuàng)建字段
    index=True  普通索引
    unique=T  唯一索引
    """
    id = Column(Integer, primary_key=True, autoincrement=True)  # primary_key=主鍵,autoincrement=自增
    name = Column(String(32))
    password = Column(String(16))
    
    __table_args__ = (
        Index('id', 'name'),  # 聯(lián)合索引
        UniqueConstraint('name', 'password', name='name_password')  # 聯(lián)合唯一索引,name索引的名字
    )
    
    # 讓查詢出來的數(shù)據(jù)顯示中文
    def __repr__(self):
        return self.name
        
Base.metadata.create_all(engine)  # 把所有集成Base類的類,創(chuàng)建表結(jié)構(gòu)

上面的代碼其實(shí)就是創(chuàng)建了一個UserInfo表,包含了三個字段,實(shí)際執(zhí)行的SQL語句如下:

CREATE TABLE `UserInfo` (
    id INTEGER NOT NULL AUTO_INCREMENT, 
    name VARCHAR(32), 
    password VARCHAR(16), 
    PRIMARY KEY (id), 
    CONSTRAINT name_password UNIQUE (name, password)
)

因?yàn)樵趧?chuàng)建引擎的時候加入了echo=True,所以執(zhí)行的SQL會在控制臺輸出出來,以便于我們排查問題。

創(chuàng)建一對多表

class Favor(Base):
    __tablename__ = 'favor'
    nid = Column(Integer, primary_key=True, autoincrement=True)
    caption = Column(String(50), default='red', unique=True)
    
class Person(Base):
    __tablename__ = 'person'
    nid = Column(Integer, primary_key=True, autoincrement=True)
    favor_id = Column(Integer, ForeignKey("favor.nid"))

創(chuàng)建多對多表

# 組
class Group(Base):
    __tablename__ = 'group'
    id = Column(Integer, primary_key=True)
    name = Column(String(64), unique=True, nullable=False)
    port = Column(Integer, default=22)
    
# 服務(wù)器
class Server(Base):
    __tablename__ = 'server'
    id = Column(Integer, primary_key=True, autoincrement=True)
    hostname = Column(String(64), unique=True, nullable=False)
    
# 服務(wù)器組,第三張表
class ServerToGroup(Base):
    __tablename__ = 'servertogroup'
    nid = Column(Integer, primary_key=True, autoincrement=True)
    server_id = Column(Integer, ForeignKey('server.id'))
    group_id = Column(Integer, ForeignKey('group.id'))

刪除表

Base.metadata.drop_all(engine)  # 把所有集成Base類的類,刪除表

操作表

增加數(shù)據(jù)

添加單條數(shù)據(jù)

MySesion = sessionmaker(bind=engine)
session = MySesion()

# 創(chuàng)建一條數(shù)據(jù)
users = UserInfo(name='Hello', password='World')

# 把數(shù)據(jù)添加到表內(nèi)
session.add(users)

# 提交生效
session.commit()

添加多少數(shù)據(jù)

session.add_all([
    UserInfo(name='A', password='1'),
    UserInfo(name='B', password='2')
])
# 提交
session.commit()
刪除數(shù)據(jù)
session.query(UserInfo).filter(UserInfo.name == 'a').delete()
session.commit()
查詢

獲取某個表中的所有內(nèi)容

result = session.query(UserInfo).all()
print(result)

修改數(shù)據(jù)

session.query(UserInfo).filter(UserInfo.id == 8).update({"name": "ffff"})
session.commit()

查詢數(shù)據(jù)

獲取所有

result = session.query(UserInfo).all()

獲取指定字段

result = session.query(UserInfo.name, UserInfo.password).all()

獲取指定的

result = session.query(UserInfo).filter_by(name='b').all()# 返回的是一個列表

獲取第一條

result = session.query(UserInfo).filter_by(name='b').first()
# 獲取值中的某個屬性
result.name

獲取數(shù)據(jù)出現(xiàn)的個數(shù)

result = session.query(UserInfo).filter_by(name='b').count()

使用and_or_進(jìn)行查詢

導(dǎo)入and_or_模塊

from sqlalchemy import and_, or_

and_

for row in session.query(UserInfo).filter(and_(UserInfo.name == 'A', UserInfo.password == 1)):
    print(row)

or_

for row in session.query(UserInfo).filter(or_(UserInfo.name == 'Hello', UserInfo.password == 1)):
    print(row)

關(guān)聯(lián)查詢

創(chuàng)建以下數(shù)據(jù)庫

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

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

engine = create_engine('mysql+pymysql://root:as@127.0.0.1:3306/tesql')

Base = declarative_base()

class Son(Base):
    __tablename__ = 'son'
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    father = relationship('Father')
    # 創(chuàng)建外鍵
    father_id = Column(Integer, ForeignKey('father.id'))
    
class Father(Base):
    __tablename__ = 'father'
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    son = relationship('Son')
    # son = relationship('Son', backref='Father') 相當(dāng)于上面兩個relationship
    
# 生成表
Base.metadata.create_all(engine)

往表里添加數(shù)據(jù)

Session = sessionmaker(bind=engine)
session = Session()

# 添加父親的數(shù)據(jù)
F = Father(name='as')
session.add(F)
session.commit()

# 添加兒子的數(shù)據(jù)
S1 = Son(name='Son1', father_id=1)
S2 = Son(name='Son2', father_id=1)
session.add_all([S1, S2])
session.commit()

# 另外一種添加數(shù)據(jù)的方式
F = session.query(Father).filter_by(id=1).first()
S3 = Son(name='Son3')
# 要用追加的方式進(jìn)行添加,F(xiàn).son是一個列表,如果不用append將會把之前的數(shù)據(jù)對應(yīng)的值進(jìn)行刪除
F.son.append(S3)
session.add(F)
session.commit()

通過父親找到所有的兒子

result = session.query(Father).filter_by(name='as').first()
for n in result.son:
    print(n.name)

通過兒子找到父親

result = session.query(Son).filter_by(name='Son2').first()
print(result.father.name, result.name)
# son = relationship('Son', backref='Father')
# print(result.father.name, result.name)

join

result = session.query(Father.name.label('kkk'), Son.name.label('ppp')).join(Son)
# label('kkk')相當(dāng)于起了一個別名,等于sql中的as
print(result)
>>>>>
SELECT father.name AS kkk, son.name AS ppp 
FROM father JOIN son ON father.id = son.father_id

多對多實(shí)例

在上面的多對多的代碼中的Server類加入一下代碼:

g = relationship("Group", secondary=ServerToGroup.__table__, backref='s')
# secondary 如果有第三張表自動加進(jìn)來

然后生成數(shù)據(jù)庫表.

添加組與主機(jī)的數(shù)據(jù)

G1 = Group(name='G1', port=22)
G2 = Group(name='G2', port=22)

S1 = Server(hostname='Linux-node1')
S2 = Server(hostname='Linux-node2')

session.add_all([G1, G2, S1, S2])
session.commit()

往第三張表里面添加關(guān)聯(lián)數(shù)據(jù)

GS1 = ServerToGroup(server_id=1, group_id=1)
GS2 = ServerToGroup(server_id=2, group_id=2)
session.add_all([GS1, GS2])
session.commit()

通過relationship進(jìn)行數(shù)據(jù)的添加

# 獲取ID=1的主機(jī)
S = session.query(Server).filter_by(id=1).first()
# 獲取所有主機(jī)組
G = session.query(Group).all()

S.g = G
# 添加數(shù)據(jù)
session.add_all([S, ])
# 提交到數(shù)據(jù)庫中
session.commit()

#Python全棧之路 #Sqlalchemy

本文名稱:2Python全棧之路系列之SQLAchemy
當(dāng)前網(wǎng)址:http://muchs.cn/article48/gddeep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、網(wǎng)站設(shè)計公司、網(wǎng)站內(nèi)鏈、面包屑導(dǎo)航、定制網(wǎng)站、網(wǎng)站策劃

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計