python之路-SQLAlchemy

SQLAchemy

SQLAlchemy是Python編程語言下的一款ORM框架,該框架建立在數據庫API之上,使用關系對象映射進行數據庫操作,簡言之便是:將對象轉換成SQL,然后使用數據API執行SQL并獲取執行結果。

安裝:

pip3 install SQLAlchemy
SQLAlchemy本身無法操作數據庫,其必須依賴pymsql等第三方插件,Dialect(用來挑選第三方api)用于和數據API進行交流,根據配置文件的不同調用不同的數據庫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...]
???
更多詳見:http://docs.sqlalchemy.org/en/latest/dialects/index.html
使用 Engine/ConnectionPooling/Dialect 進行數據庫操作,Engine使用ConnectionPooling連接數據庫,然后再通過Dialect執行SQL語句。
from sqlalchemy import create_engine
??
??
engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/t1", max_overflow=5)
??
# 執行SQL
# cur = engine.execute(
#???? "INSERT INTO hosts (host, color_id) VALUES ('1.1.1.22', 3)"
# )
??
# 新插入行自增ID
# cur.lastrowid
??
# 執行SQL
# cur = engine.execute(
#???? "INSERT INTO hosts (host, color_id) VALUES(%s, %s)",[('1.1.1.22', 3),('1.1.1.221', 3),]
# )
??
??
# 執行SQL
# cur = engine.execute(
#???? "INSERT INTO hosts (host, color_id) VALUES (%(host)s, %(color_id)s)",
#???? host='1.1.1.99', color_id=3
# )
??
# 執行SQL
# cur = engine.execute('select * from hosts')
# 獲取第一行數據
# cur.fetchone()
# 獲取第n行數據
# cur.fetchmany(3)
# 獲取所有數據
# cur.fetchall()
ORM功能使用

使用 ORM/Schema Type/SQL Expression Language/Engine/ConnectionPooling/Dialect 所有組件對數據進行操作。根據類創建對象,對象轉換成SQL,執行SQL。

創建表單

from sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Indexfrom sqlalchemy.orm import sessionmaker, relationshipfrom sqlalchemy import create_engineengine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/t1", max_overflow=5)    #此處必須是雙引號

Base = declarative_base()# 創建單表class Users(Base):__tablename__ = 'users'#此處就是創建表的表名
id = Column(Integer, primary_key=True)#此處創建了三列name = Column(String(32))extra = Column(String(16))__table_args__ = (UniqueConstraint('id', 'name', name='uix_id_name'), #創建外建Index('ix_id_name', 'name', 'extra')                   #創建索引
    )def __repr__(self):#這個函數的作用是打印時期作用#直接print(ret)#就可以看到想要的結果。temp = '%s-%s-%s' % (self.id, self.name, self.extra)return temp# 一對多 
class Favor(Base):__tablename__ = 'favor' nid = Column(Integer, primary_key=True) caption = Column(String(50), default='red', unique=True) 
class Person(Base): __tablename__ = 'person' nid = Column(Integer, primary_key=True) name = Column(String(32), index=True, nullable=True) favor_id = Column(Integer, ForeignKey("favor.nid")) 
# 多對多 
class Group(Base):__tablename__ = 'group' id = Column(Integer, primary_key=True) name = Column(String(64), unique=True, nullable=False) 
class Server(Base):__tablename__ = 'server' id = Column(Integer, primary_key=True, autoincrement=True)   hostname = Column(String(64), unique=True, nullable=False)port = Column(Integer, default=22)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'))def init_db():Base.metadata.create_all(engine)#創建所有表def drop_db():Base.metadata.drop_all(engine)#刪除所有表

?

?

?

操作表

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy import create_engineengine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/t1", max_overflow=5)Base = declarative_base()# 創建單表
class Users(Base):__tablename__ = 'users'id = Column(Integer, primary_key=True)name = Column(String(32))extra = Column(String(16))__table_args__ = (UniqueConstraint('id', 'name', name='uix_id_name'),Index('ix_id_name', 'name', 'extra'),)def __repr__(self):return "%s-%s" %(self.id, self.name)# 一對多
class Favor(Base):__tablename__ = 'favor'nid = Column(Integer, primary_key=True)caption = Column(String(50), default='red', unique=True)def __repr__(self):return "%s-%s" %(self.nid, self.caption)class Person(Base):__tablename__ = 'person'nid = Column(Integer, primary_key=True)name = Column(String(32), index=True, nullable=True)favor_id = Column(Integer, ForeignKey("favor.nid"))# 與生成表結構無關,僅用于查詢方便favor = relationship("Favor", backref='pers')     #此處的作用就是聯表,會把favor表中的數據讀出來,不用我們去寫聯表語句。必須與關聯的表中有foreignkey才可以。# backref的作用就是在favor表中加了一個pers的字段,.pers就表示與favor相關的所有信息#正向查詢
ret = session.query(Person)
print(ret)
for obj in ret:print(obj.nid,obj.name,obj.favor_id,obj.favor.captiom)# 反向查詢
# obj = session.query(Group).filter(Group.caption =='DBA').first()
# print(obj.nid)
# print(obj.caption)
# print(obj.uuu)
#通過查找Group中在DBA組的成員,如果relationship中的backref指定uuu,那么,.uuu就把realtionship所關聯表中的所有在DBA中的成員列出來。# 多對多
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'))group = relationship("Group", backref='s2g')server = relationship("Server", backref='s2g')class Group(Base):__tablename__ = 'group'id = Column(Integer, primary_key=True)name = Column(String(64), unique=True, nullable=False)port = Column(Integer, default=22)# group = relationship('Group',secondary=ServerToGroup,backref='host_list')class Server(Base):__tablename__ = 'server'id = Column(Integer, primary_key=True, autoincrement=True)hostname = Column(String(64), unique=True, nullable=False)def init_db():Base.metadata.create_all(engine)def drop_db():Base.metadata.drop_all(engine)Session = sessionmaker(bind=engine)     #如果想操作數據庫必須要創建這個session
session = Session()

?

?

obj = Users(name="alex0", extra='sb')  增加一條數據
session.add(obj) session.add_all([ 批量增加
Users(name
="alex1", extra='sb'),Users(name="alex2", extra='sb'), ]) session.commit()


session.query(Users).filter(Users.id > 2).delete()  如果想用and的話,就在〉2后面加,然后再跟條件
session.commit()


session.query(Users).filter(Users.id > 2).update({"name" : "099"})
session.query(Users).filter(Users.id > 2).update({Users.name: Users.name + "099"}, synchronize_session=False) 字符串相加
session.query(Users).filter(Users.id > 2).update({"num": Users.num + 1}, synchronize_session="evaluate")      數字相加
session.commit()


ret = session.query(Users).all() 不加.all()print(ret)就會看到執行語句
如果想查看的話,可以執行:
print(ret[0].name) 因為ret是個列表,表中有幾列,列表中就會有幾個元素。
ret
= session.query(Users.name, Users.extra).all() ret = session.query(Users).filter_by(name='alex').all() ret = session.query(Users).filter_by(name='alex').first()

其他:

# 條件
ret = session.query(Users).filter_by(name='alex').all()
ret = session.query(Users).filter(Users.id > 1, Users.name == 'eric').all()
ret = session.query(Users).filter(Users.id.between(1, 3), Users.name == 'eric').all()
ret = session.query(Users).filter(Users.id.in_([1,3,4])).all() 在這個范圍
ret = session.query(Users).filter(~Users.id.in_([1,3,4])).all() 波浪號代表非
ret = session.query(Users).filter(Users.id.in_(session.query(Users.id).filter_by(name='eric'))).all()
from sqlalchemy import and_, or_
ret = session.query(Users).filter(and_(Users.id > 3, Users.name == 'eric')).all()
ret = session.query(Users).filter(or_(Users.id < 2, Users.name == 'eric')).all()
ret = session.query(Users).filter(or_(Users.id < 2,and_(Users.name == 'eric', Users.id > 3),Users.extra != "")).all()# 通配符
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 funcret = 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() 此處的join默認是inner joinret = session.query(Person).join(Favor, isouter=True).all() outer表示leftjoin# 組合
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()  不會去重

?多對多的操作:

多對多連表操作

需求以及數據庫結構

需求:

三張表:

  1. 主機表:包括nid hostname port ip
  2. 管理員表:包括:nid username
  3. 主機對應管理員表: nid 主機id,管理員id

一個管理員帳號(比如root),可以關聯多臺服務器,一個服務器也可以有多個管理員帳號

先來看下數據結構吧:

from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index from sqlalchemy.orm import sessionmaker, relationship engine = create_engine("mysql+pymysql://root:7ujm8ik,@192.168.4.193:3306/testsql?charset=utf8", max_overflow=5) Base = declarative_base() #多對多 class HostToHostUser(Base): __tablename__ = 'host_to_host_user' id = Column(Integer, primary_key=True,autoincrement=True) host_id = Column(Integer,ForeignKey('host.id')) host_user_id = Column(Integer,ForeignKey('host_user.nid')) #多對多操作 host = relationship('Host',backref='h')#backref='h'表示host表自動生成某種關聯關系,這個關系就成為‘h’關系,只要下邊某個表中的backref也指明了這個關系‘h’,那么host表就會與該表形成關聯,基于'h'關系,這是道不清理不明的一種關系 host_user = relationship('HostUser',backref='u')#backref='u'表示host_user表自動生成某種關聯關系,只要下邊某個表中的backref也指明了這個關系‘u‘,那么host_user表就會與該表形成關聯,基于'u'關系 (如果某張表中寫了關聯關系,關系表中就可以不用寫了)
#查詢方法:host_obj = session.query(Host).filter(Host.hostname =='c1').first()
print(host_obj.host_user) class Host(Base): __tablename__ = 'host' nid = Column(Integer, primary_key=True,autoincrement=True) hostname = Column(String(32)) port = Column(String(32)) ip = Column(String(32)) ####最簡單的方式,添加此行就行(另外一種方法,可以將關系放在某張表中): host_user=relationship('HostUser',secondary=HostToHostUser.__table__,backref='h')#這里backref指明了‘h’關系,那么host表就會與host_user表生成關聯關系 ?#格式:表名(本類是host表,這里寫要跟host關聯的表)=relationship('對象名(本類是host表,這里寫要跟host關聯的表的對象名)',?secondary=中間表的對象名, backref=關聯關系'h') class HostUser(Base): __tablename__ = 'host_user' nid = Column(Integer, primary_key=True,autoincrement=True) username = Column(String(32)) def init_db(): Base.metadata.create_all(engine) # init_db() def drop_db(): Base.metadata.drop_all(engine) Session = sessionmaker(bind=engine) session = Session() #======多對多操作 # session.add_all([ # Host(hostname='c1',port='22',ip='1.1.1.1'), # Host(hostname='c2',port='22',ip='1.1.1.2'), # Host(hostname='c3',port='22',ip='1.1.1.3'), # Host(hostname='c4',port='22',ip='1.1.1.4'), # Host(hostname='c5',port='22',ip='1.1.1.5'), # ]) # session.commit() # session.add_all([ # HostUser(username='root'), # HostUser(username='db'), # HostUser(username='nb'), # HostUser(username='sb'), # ]) # session.commit() # session.add_all([ # HostToHostUser(host_id=1,host_user_id=1), # HostToHostUser(host_id=1,host_user_id=2), # HostToHostUser(host_id=1,host_user_id=3), # HostToHostUser(host_id=2,host_user_id=2), # HostToHostUser(host_id=2,host_user_id=4), # HostToHostUser(host_id=2,host_user_id=3), # ]) # session.commit()

虛擬關系的查詢

需求:查詢主機C1的管理員帳號

# 1.反向查找,查詢host表中c1的信息,會得到一個對象,對象中存在一個已經設置好的虛擬關系:h
host_obj = session.query(Host).filter(Host.hostname == 'c1').first() #2.正向查找,遍歷對象屬性 for item in host_obj.h: print(item.host_user.username)

(整個過程經歷了一個循環,通過host找到hosttouser,在通過hosttouser中的backref的h,列出所有與c1有關的數據)

結果:

root
db
nb

注意:多對多的話,正反查詢都是遍歷對象中的屬性

同一需求最簡單的方式

需求還是同上:查詢主機C1的管理員帳號

需要在兩張表的一張表中加一條host_user=relationship('HostUser',secondary=HostToHostUser.__table__,backref='h'),我加到了host表中

#最簡單的查詢方式:host_obj = session.query(Host).filter(Host.hostname == 'c1').first() print(host_obj.host_user) for item in host_obj.host_user: print(item.username)

結果:

[<__main__.HostUser object at 0x103778710>, <__main__.HostUser object at 0x103778d68>, <__main__.HostUser object at 0x103778e10>] root db nb

轉載于:https://www.cnblogs.com/l-w-q/p/6265485.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/373128.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373128.shtml
英文地址,請注明出處:http://en.pswp.cn/news/373128.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

POJ 1751 Highways

題意&#xff1a;n個城市&#xff0c;然后把n個城市的坐標都給你&#xff0c;然后給你m條已經修好的道路&#xff0c;然后給出m個已經修好道路的城市a&#xff0c;b&#xff0c; However, they want to guarantee that every town is highway-reachable from every other town.…

C語言編程中void什么意思,程序設計中遇到的void到底是什么意思

部分編程的初學者都會問"void是什么意思","為什么很多函數前都要加個void".實際上,void最簡單的解釋就是把0轉換成空類型的意思。下面用各個開發語言來詳解void1.C語言中的void表示空類型&#xff0c;它跟int&#xff0c;float是同地位的&#xff0c;一般用…

Linux中vim編輯器的縮進的功能鍵

vim編程時,經常需要對代碼進行縮進處理,以增加程序的可讀性和后期的代碼維護. 可以采用多種方式達到縮進的目的: 1) 命令模式(command mode) 2) Visual模式&#xff08;visual mode&#xff09; 2) 輸入模式(entry mode) 3) 末行模式(last-line mode) 4) 在/etc/vimrc有給予vim…

JSF 2,PrimeFaces 3,Spring 3和Hibernate 4集成項目

本文展示了如何集成JSF2&#xff0c;PrimeFaces3&#xff0c;Spring3和Hibernate4技術。 它為Java開發人員提供了一個通用的項目模板。 另外&#xff0c;如果Spring不用于業務和數據訪問層&#xff0c;則可以提供JSF – PrimeFaces和Hibernate集成項目。 二手技術&#xff1a…

c語言編程文件中刪除數據結構,C語言數據結構實戰(一)順序表的插入與刪除

今天學習了思成老師的數據結構實戰教程 寫了一個順序表 插入和刪除的操作 把源碼共享給大家 一共包括list.c stu.h main.c list.h .h文件是頭文件 需要引入 具體的功能我都已經在代碼中寫明了list.h代碼如下&#xff1a;//線性表的定義在頭文件中實現#ifndef _LIST_H#define …

內存使用分析工具Valgrind簡單用法

轉載自 http://www.cnblogs.com/sunyubo/archive/2010/05/05/2282170.html 暫時還未使用過&#xff0c;記錄下&#xff0c;記錄下&#xff0c;記錄下 Valgrind的主要作者Julian Seward剛獲得了今年的Google-OReilly開源大獎之一──Best Tool Maker。讓我們一起來看一下他的作品…

Lucene概述第一部分:創建索引

介紹 我最近一直在與開源搜索引擎Lucene合作 。 我不是專家&#xff0c;但是由于我只是瀏覽了一些相當稀疏的文檔并將應用程序從Lucene的很舊的版本遷移到了最新版本的2.4&#xff0c;所以我在總體上很清楚。 Lucene的文檔有點讓人難以想象&#xff0c;因此我想趁此機會在我腦海…

初識openstack

一、 什么是openstack&#xff1f; OpenStack是一個由NASA&#xff08;美國國家航空航天局&#xff09;和Rackspace合作研發并發起的&#xff0c;以Apache許可證授權的自由軟件和開放源代碼項目。 二、openstack前世今身 openstack是一個跟Eucalyptus,AWS(Amazon web Service)類…

c語言case多語句的取值,Switch Case語句中多個值匹配同一個代碼塊的寫法

C&num;&plus;JQuery&plus;&period;Ashx&plus;百度Echarts實現全國省市地圖和餅狀圖動態數據圖形報表的統計在目前的一個項目中,需要用到報表表現數據,這些數據有多個維度,需要同時表現出來,同時可能會有大量數據呈現的需求,經過幾輪挑選,最終選擇了百度的e…

php解決下單、抽獎并發導致的庫存負數的問題

我們知道數據庫處理sql是一條條處理的&#xff0c;假設購買商品的流程是這樣的&#xff1a; sql1:查詢商品庫存 if(庫存數量 > 0) { //生成訂單... sql2:庫存-1 } 當沒有并發時&#xff0c;上面的流程看起來是如此完美&#xff0c;假設同時兩個人下單&#xff0c;而…

在Spring中使用JDBCJobStore配置Quartz

我將開始一些有關Quartz Scheduler內部&#xff0c;提示和技巧的系列文章&#xff0c;這是第0章-如何配置持久性作業存儲。 在Quartz中&#xff0c;您基本上可以在將作業和觸發器存儲在內存中以及在關系數據庫中進行選擇&#xff08; Terracotta是最近添加的混合功能&#xff0…

rlwrap插件,實現sqlplus上下翻頁

oracle在Linux下&#xff0c;sqlplus中不能上下翻&#xff0c;最主要我經常打錯字&#xff01;嘿嘿 01、下載 RPM &#xff1a;http://rpmfind.net/linux/rpm2html/search.php?queryrlwrap tar.gz:https://fossies.org/linux/privat/rlwrap-0.42.tar.gz/ 百度云&#xff1a;h…

ice庫c語言例子,很不多的ICE架構入門學習例子

雖然使用傳統的SOCKET編程&#xff0c;我們可以更為清楚程序的性能&#xff0c;能夠更直接的操控SOCKET的設置&#xff0c;比如發送超時時間&#xff0c;接受BUFFER的大小&#xff0c;以及進行自己的協議加密。但是由于其調試成本較高&#xff0c;且不易于分布式部署ICE 作為一…

程序員的十個層次,你屬于哪一層?(轉)

自西方文藝復興以來&#xff0c;中國在自然科學方面落后西方很多&#xff0c;軟件領域也不例外。當然現在中國的許多程序員們對此可能有許多不同的意見&#xff0c;有些人認為中國的程序員水平遠落后于西方&#xff0c;有些則認為中國的程序員個人能力并不比西方的程序員差&…

操作系統基礎篇

程序運行的4個因素 (1).程序設計語言 (2).編譯系統 (3).操作系統 (4).指令集結構&#xff08;硬件系統&#xff09; 操作系統的定義&#xff1a;操作系統是掌控計算機上所有事情的軟件系統(硬件資源&#xff0c;軟件資源) 操作系統對內存&#xff0c;i/o&#xff0c;cpu&#x…

高效快速中值濾波算法c語言,快速中值濾波及c語言實現.docx

...快速中值濾波及c語言實現學生姓名&#xff1a; 劉 勇 學 號&#xff1a; 6100410218 專業班級&#xff1a; 數媒101【摘要】本文討論了用c語言在微機上實現中值濾波及快速算法&#xff0c;在程序設計的過程中充分考慮到程序運行的時間復雜度和空間復雜度的問題&#xff0e;解…

Arquillian 1.0.0.Final正式發布! 準備使用GlassFish和WebLogic! 殺死所有蟲子!

紅帽公司和JBoss社區今天宣布的1.0.0.Final發布的Arquillian &#xff0c;其屢獲殊榮的建在Java虛擬機&#xff08;JVM&#xff09;運行測試平臺。 Arquillian大大減少了編寫和執行Java中間件集成和功能測試所需的工作。 它甚至使測試工程師能夠解決以前認為無法測試或測試成本…

Jquery選擇器特殊字符問題

場景&#xff1a; $("#" AAA "")&#xff0c;AAA代表某表單ID 當AAA為普通字符串時&#xff0c;ok&#xff1b; 當AAA含有特殊符號時&#xff08;eg:a.b&#xff09;&#xff0c;獲取不到該對象&#xff1b; 原因&#xff1a;特殊符號會進行轉義&#xf…

qq五筆linux,QQ五筆 - 五筆小字典 QQ綁定很實用

九、 智能調頻、空碼檢索、詞序固定在QQ五筆中還有一些小亮點&#xff0c;比如它可以根據“最近輸入”、“輸入次數”對候選詞排序。同時為了加快檢索速度&#xff0c;默認只在常用字庫(GB2312)中檢索&#xff0c;只有出現空碼后才會繼續搜索容量更大的GBK字庫&#xff0c;很好…

DFS:C 小Y的難題(1)

解題心得&#xff1a; 1、在明確使用DFS之后一定要找到遞歸函數的出口、方向&#xff0c;以及遞歸的點&#xff08;在某個情況下開始遞歸&#xff09;(void 也可以return&#xff0c;但是沒有返回值)。遞歸時也要有遞歸的方向&#xff0c;最后都能夠達到遞歸的出口。 2、在DF…