python之SQLAlchemy ORM
前言:?這篇博客主要介紹下SQLAlchemy及基本操作,寫完后有空做個堡壘機小項目。有興趣可看下python之數據庫(mysql)操作。下篇博客整理寫篇關于Web框架和django基礎~~
一、ORM介紹
orm英文全稱object relational mapping,就是對象映射關系程序,簡單來說我們類似python這種面向對象的程序來說一切皆對象,但是我們使用的數據庫卻都是關系型的,為了保證一致的使用習慣,通過orm將編程語言的對象模型和數據庫的關系模型建立映射關系,這樣我們在使用編程語言對數據庫進行操作的時候可以直接使用編程語言的對象模型進行操作就可以了,而不用直接使用sql語言。
orm的優點:
- 隱藏了數據訪問細節,“封閉”的通用數據庫交互,ORM的核心。他使得我們的通用數據庫交互變得簡單易行,并且完全不用考慮該死的SQL語句。快速開發,由此而來。
- ORM使我們構造固化數據結構變得簡單易行。
缺點:
- 無可避免的,自動化意味著映射和關聯管理,代價是犧牲性能(早期,這是所有不喜歡ORM人的共同點)。現在的各種ORM框架都在嘗試使用各種方法來減輕這塊(LazyLoad,Cache),效果還是很顯著的。
?
二、SQLAlchemy框架與數據庫API
在Python中,最有名的ORM框架是SQLAlchemy。用戶包括openstack\Dropbox等知名公司或應用,主要用戶列表http://www.sqlalchemy.org/organizations.html#openstack
需要自己把數據庫中的表映射成類,然后才能通過對象的方式去調用。SQLAlchemy不止可以支持MYSQL,還可以支持Oracle等。
Dialect用于和數據API進行交流,根據配置文件的不同調用不同的數據庫API,從而實現對數據庫的操作:
MySQL-Pythonmysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>pymysqlmysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]MySQL-Connectormysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname>cx_Oracleoracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...]更多詳見:http://docs.sqlalchemy.org/en/latest/dialects/index.html安裝SQLAlchemy:
pip install SQLAlchemy?
三、連接數據庫并查詢
1 from sqlalchemy import create_engine 2 3 #連接數據庫,生成engine對象;最大連接數為5個 4 engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/zcl", max_overflow=5) 5 print(engine) #Engine(mysql+pymysql://root:***@127.0.0.1:3306/zcl) 6 result = engine.execute('select * from students') #不用commit(),會自動commit 7 print(result.fetchall())輸出:
Engine(mysql+pymysql://root:***@127.0.0.1:3306/zcl) [(1, 'zcl', 'man', 22, '15622341234', None), (2, 'alex', 'man', 30, '15622341235', None), (5, 'Jack', 'man', 25, '1351234', 'CN'), (6, 'Mary', 'female', 18, '1341234', 'USA'), (10, 'Jack', 'man', 25, '1351234', 'CN'), (11, 'Jack2', 'man', 25, '1351234', 'CN'), (12, 'Mary', 'female', 18, '1341234', 'USA'), (13, 'cjy', 'man', 18, '1562234', 'USA'), (14, 'cjy2', 'man', 18, '1562235', 'USA'), (15, 'cjy3', 'man', 18, '1562235', 'USA'), (16, 'cjy4', 'man', 18, '1562235', 'USA'), (17, 'cjy5', 'man', 18, '1562235', 'USA')] View Code?
四、創建表
創建user與color表: 創建表時需要與MetaData的實例綁定。
1 from sqlalchemy import create_engine, \ 2 Table, Column, Integer, String, MetaData, ForeignKey 3 4 metadata = MetaData() #相當于實例一個父類 5 6 user = Table('user', metadata, #相當于讓Table繼承metadata類 7 Column('id', Integer, primary_key=True), 8 Column('name', String(20)), 9 ) 10 11 color = Table('color', metadata, #表名color 12 Column('id', Integer, primary_key=True), 13 Column('name', String(20)), 14 ) 15 engine = create_engine("mysql+pymysql://root:root@localhost:3306/zcl", max_overflow=5) 16 17 metadata.create_all(engine) #table已經與metadate綁定查看創建的表:
?
五、增刪改查
1. 先來了解下原生sql語句的增刪改查:
1 from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey,select 2 3 metadata = MetaData() 4 5 user = Table('user', metadata, 6 Column('id', Integer, primary_key=True), 7 Column('name', String(20)), 8 ) 9 10 color = Table('color', metadata, 11 Column('id', Integer, primary_key=True), 12 Column('name', String(20)), 13 ) 14 engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/zcl", max_overflow=5) 15 16 conn = engine.connect() #創建游標,當前實例所處狀態 17 18 # 創建SQL語句,INSERT INTO "user" (id, name) VALUES (:id, :name) 19 #id號可省略,默認是自增的 20 # conn.execute(user.insert(), {'id': 1, 'name': 'zcl'}) 21 # conn.close() 22 23 # sql = user.insert().values(name='wu') #插入 24 # conn.execute(sql) 25 # conn.close() 26 27 #刪除id號大于1的行,也可以where(user.c.name=="zcl") 28 # sql = user.delete().where(user.c.id > 1) 29 # conn.execute(sql) 30 # conn.close() 31 32 # 將name=="wuu"更改為"name=="ed" 33 # sql = user.update().where(user.c.name == 'wuu').values(name='ed') 34 # conn.execute(sql) 35 # conn.close() 36 37 #查詢 下面不能寫 sql = user.select... 會曝錯 38 #sql = select([user, ]) #[(1, 'zcl'), (9, 'ed'), (10, 'ed')] 39 # sql = select([user.c.id, ]) #[(1,), (9,), (10,)] 40 sql = select([user.c.name, color.c.name]).where(user.c.id==color.c.id) 41 # sql = select([user.c.name]).order_by(user.c.name) 42 # sql = user.select([user]).group_by(user.c.name) 43 44 result = conn.execute(sql) 45 print(result.fetchall()) 46 conn.close()?
2. 通過SQLAlchemy的增刪改查(重要):
1 from sqlalchemy import create_engine 2 from sqlalchemy.ext.declarative import declarative_base 3 from sqlalchemy import Column,Integer,String 4 from sqlalchemy.orm import sessionmaker 5 6 Base = declarative_base() #生成一個SqlORM基類(已經封裝metadata) 7 #echo=True可以查看創建表的過程 8 engine = create_engine("mysql+pymysql://root:root@localhost:3306/zcl", echo=True) 9 10 class Host(Base): 11 __tablename__ = 'hosts' #表名為host 12 id = Column(Integer, primary_key=True, autoincrement=True) 13 hostname = Column(String(64), unique=True, nullable=False) 14 ip_addr = Column(String(128), unique=True, nullable=False) 15 port = Column(Integer, default=22) 16 17 18 Base.metadata.create_all(engine) #創建所有表結構 19 20 if __name__ == '__main__': 21 #創建與數據庫的會話sessionclass,注意,這里返回給session的是個class類,不是實例 22 SessionCls=sessionmaker(bind=engine) 23 session=SessionCls() #連接的實例 24 #準備插入數據 25 h1 = Host(hostname='localhost', ip_addr='127.0.0.1') #實例化(未創建) 26 h2 = Host(hostname='ubuntu', ip_addr='192.168.2.243', port=20000) 27 28 #session.add(h1) #也可以用下面的批量處理 29 #session.add_all([h1,h2]) 30 #h2.hostname='ubuntu_test' #只要沒提交,此時修改也沒問題 31 32 #查詢數據,返回一個對象 33 obj = session.query(Host).filter(Host.hostname=="localhost").first() 34 print("-->",obj) 35 #[<__main__.Hostobjectat0x00000000048DC0B8>]如果上面為.all() 36 #<__main__.Hostobjectat0x000000000493C208>如果上面為.first() 37 38 #如果用.all(),會曝錯AttributeError:'list'objecthasnoattribute'hostname' 39 #obj.hostname = "localhost_1" #將主機名修改為localhost_1 40 41 session.delete(obj) #刪除行 42 43 session.commit()#提交操作結果截圖:
?
六、外鍵關聯
1. 創建主機表hosts與分組表group,并建立關聯,即一個組可對應多個主機:
1 from sqlalchemy import create_engine 2 from sqlalchemy.ext.declarative import declarative_base 3 from sqlalchemy import Column, Integer, String,ForeignKey 4 from sqlalchemy.orm import sessionmaker,relationship 5 6 Base = declarative_base() # 生成一個SqlORM 基類(已經封閉metadata) 7 #echo=True可以查看創建表的過程 8 engine = create_engine("mysql+pymysql://root:root@localhost:3306/zcl", echo=True) 9 10 class Host(Base): 11 __tablename__ = 'hosts' #表名 12 id = Column(Integer, primary_key=True, autoincrement=True) #默認自增 13 hostname = Column(String(64), unique=True, nullable=False) 14 ip_addr = Column(String(128), unique=True, nullable=False) 15 port = Column(Integer, default=22) 16 #外鍵關聯,主機與組名關聯,一個組對應多個主機 17 group_id = Column(Integer, ForeignKey("group.id")) 18 19 20 class Group(Base): 21 __tablename__ = "group" 22 id = Column(Integer,primary_key=True) 23 name = Column(String(64), unique=True, nullable=False) 24 25 26 Base.metadata.create_all(engine) # 創建所有表結構 27 28 if __name__ == '__main__': 29 # 創建與數據庫的會話session class ,注意,這里返回給session的是個class,不是實例 30 SessionCls = sessionmaker(bind=engine) 31 session = SessionCls() #連接的實例 32 33 session.commit() #提交查看結果:
?
問題: 查看新建的group表結構或從group表查詢會發現desc group;select * from group都會曝錯!!(為什么會產生這種錯誤可能是group與數據庫有某些關聯導致的,eg:group by... 我猜的)
解決方法: 用desc zcl.group; select * from zcl.group; ?(zcl為數據庫名)
?
2. 創建完表后就要在表中創建數據啦。接下來在hosts表與group表創建數據:
1 from sqlalchemy import create_engine 2 from sqlalchemy.ext.declarative import declarative_base 3 from sqlalchemy import Column, Integer, String,ForeignKey 4 from sqlalchemy.orm import sessionmaker 5 6 Base = declarative_base() # 生成一個SqlORM 基類(已經封閉metadata) 7 #echo=True可以查看創建表的過程 8 engine = create_engine("mysql+pymysql://root:root@localhost:3306/zcl", echo=True) 9 10 class Host(Base): 11 __tablename__ = 'hosts' #表名 12 id = Column(Integer, primary_key=True, autoincrement=True) #默認自增 13 hostname = Column(String(64), unique=True, nullable=False) 14 ip_addr = Column(String(128), unique=True, nullable=False) 15 port = Column(Integer, default=22) 16 #外鍵關聯,主機與組名關聯 17 group_id = Column(Integer, ForeignKey("group.id")) 18 19 20 class Group(Base): 21 __tablename__ = "group" 22 id = Column(Integer,primary_key=True) 23 name = Column(String(64), unique=True, nullable=False) 24 25 Base.metadata.create_all(engine) # 創建所有表結構 26 27 if __name__ == '__main__': 28 # 創建與數據庫的會話session class ,注意,這里返回給session的是個class,不是實例 29 SessionCls = sessionmaker(bind=engine) 30 session = SessionCls() #連接的實例 31 32 g1 = Group(name = "g1") 33 g2 = Group(name = "g2") 34 g3 = Group(name = "g3") 35 g4 = Group(name = "g4") 36 session.add_all([g1,g2,g3,g4]) 37 38 #此時上面的g1,g2,g3三條記錄還未存在,因為程序運行到這一行時還未commit(),故g1.id也未存在,但是下面一行代碼是用到g1.id的!!經過測試: 運行時雖然不曝錯,但關聯不成功,如下圖 39 h1 = Host(hostname='localhost', ip_addr='127.0.0.1',group_id=g1.id) 40 session.add(h1) 41 42 session.commit() #提交經過測試: 運行時雖然不曝錯,但關聯不成功,如下圖:
?
3. 現在問題又來了,hosts表中的group_id可是為空啊!! 這肯定不行的。現在如何在不刪除hosts表數據的前提下,使group_id不為空(eg: 使group_id為4,與g4建立關聯)??可用下面的代碼:
g4 = session.query(Group).filter(Group.name=="g4").first() #找到g4組的對象 h = session.query(Host).filter(Host.hostname=="localhost").update({"group_id":g4.id}) #更新(修改) session.commit() #提交?
4. 問題: 如何獲取與主機關聯的group_id??
g4=session.query(Group).filter(Group.name=="g4").first() h=session.query(Host).filter(Host.hostname=="localhost").first() print("h1:",h.group_id)好吧,我承認這個問題太簡單了,通過上面的代碼,找到主機的對象h, 則h.group_id就是答案。接下來的問題才是重點。
?
5.?此時可以獲取已經關聯的group_id,但如何獲取已關聯的組的組名??
print(h.group.name) #AttributeError:'Host'object has no attribute 'group'嗯,你是初學者,你當然會說通過過h.group.name就可以找到與主機關聯的組名! BUT,這是不行的,會曝錯,因為Host類根本就沒有group屬性!!
解決方法:
- first:
- second:
在Host類中加入group = relationship("Group"):
class Host(Base):__tablename__ = 'hosts' #表名id = Column(Integer, primary_key=True, autoincrement=True) #默認自增hostname = Column(String(64), unique=True, nullable=False)ip_addr = Column(String(128), unique=True, nullable=False)port = Column(Integer, default=22)#外鍵關聯,主機與組名關聯group_id = Column(Integer, ForeignKey("group.id"))group = relationship("Group")此時再用print(h.group.name)就不會曝錯啦!!
?
6. 哈哈,問題還沒完呢。?前面已經實現:通過主機可查看對應組名,那么如何實現通過組名查看對應的主機??
經過前面5個點的歷練,你已成為小小的老司機了,于是你很自信地說: 和第5個點一樣,在Group類中加入hosts = relationship("Host");
1 class Host(Base): 2 __tablename__ = 'hosts' #表名 3 id = Column(Integer,primary_key=True, autoincrement=True) #默認自增 4 hostname = Column(String(64), unique=True, nullable=False) 5 ip_addr = Column(String(128), unique=True, nullable=False) 6 port = Column(Integer, default=22) 7 #外鍵關聯,主機與組名關聯 8 group_id = Column(Integer,ForeignKey("group.id")) 9 group = relationship("Group") 10 11 class Group(Base): 12 __tablename__ = "group" 13 id = Column(Integer, primary_key=True) 14 name = Column(String(64), unique=True, nullable=False) 15 hosts = relationship("Host") 16 17 Base.metadata.create_all(engine) #創建所有表結構 18 19 g4 = session.query(Group).filter(Group.name=="g4").first() 20 h = session.query(Host).filter(Host.hostname=="localhost").first() 21 print("h1:",h.group_id) #h1: 4 22 #此時可以獲取已經關聯的group_id,但如何獲取已關聯的組的組名 23 print(h.group.name) #g4 24 print("g4:",g4.hosts) #g4:[<__main__.Hostobjectat0x0000000004303860>] View Code?
7. 通過上面的兩句代碼可實現雙向關聯。但必須在兩個表都加上一句代碼才行,有沒有辦法只用一句代碼就實現雙向關聯???當然有,老司機會這么做:?
在Host類中加入下面這句代碼,即可實現雙向關聯:
group=relationship("Group",backref="host_list")?
八、合并查詢join
合并查詢分為: inner join、left outer join、right outer join、full outer join
下面的例子可以讓你完全理解join:?http://stackoverflow.com/questions/38549/what-is-the-difference-between-inner-join-and-outer-join
關于join的原生sql操作:
?
在SQLAlchemy實現sql.join:
obj = session.query(Host).join(Host.group).all() #相當于inner join print("-->obj:",obj)?
?
九、分類聚合group by
group by是啥意思呢? 我說下我的理解吧,group即分組,by為通過;合起來即: 通過XX分組;
舉個例子吧,現在有兩張表,分別是主機表與分組表。兩表已經通過group_id建立關聯,分組表中有4個數據,分別為g1,g2,g3,g4; id分別為1,2,3,4; 而主機表有3個數據,group_id分別為4,3,4; id分別為1,2,4; 現在對hosts表執行group by命令,進行分類聚合。
具體請看下圖:
對應SQLAlchemy語句:
obj1 = session.query(Host).join(Host.group).group_by(Group.name).all() #分類聚合 print("-->obj1:",obj1)?
對應SQLAlchemy語句:
obj2 = session.query(Host,func.count(Group.name)).join(Host.group).group_by(Group.name).all() print("-->obj2:",obj2)輸出: -->obj2: [(<__main__.Host object at 0x0000000003C854A8>, 1), (<__main__.Host object at 0x0000000003C85518>, 2)]?
十、多對多關聯
多對多關聯,即: 一個主機h1可對應在多個組(g1,g2),一個組(g1)可對應多個主機(h1,h2)
想實現如下的多對多關聯,需要一張中間表。Eg:h1 g1h1 g2h2 g1Host表h1h2h3 Group表g1 g2g3HostToGroup中間表(實現多對多關聯,sqlalchemy也是這樣實現的)id host_id group_id1 1 12 1 23 2 1雖然有了中間表,但如果想查看一個組對應的所有主機名或者一個主機對應的所有組,還是需要Group/Host與中間表進行一系列的關聯操作(join~), 但SqlAlchemy簡化了關聯操作!!
調用下面命令便會自動關聯中間表:
Host.groups() #查看一個主機對應所有組 Group.hosts()?
SQLAlchemy是如何實現多對多關聯的??
1. 建立中間表,關聯其它兩個表
1 from sqlalchemy import create_engine,func,Table 2 from sqlalchemy.ext.declarative import declarative_base 3 from sqlalchemy import Column, Integer, String,ForeignKey 4 from sqlalchemy.orm import sessionmaker,relationship 5 6 Base = declarative_base() # 生成一個SqlORM 基類(已經封閉metadata) 7 #echo=True可以查看創建表的過程 8 engine = create_engine("mysql+pymysql://root:root@localhost:3306/zcl", echo=True) 9 10 11 #直接創建表并返回表的實例 Host2Group主動關聯Host與Group(被關聯) 12 Host2Group = Table('host_to_group',Base.metadata, 13 Column('host_id',ForeignKey('host.id'),primary_key=True), 14 Column('group_id',ForeignKey('group.id'),primary_key=True), 15 #一個表為什么能創建兩個主鍵(其實是兩個列同時作為主鍵,非空且唯一) 16 #PRIMARY KEY (host_id, group_id), 17 )2.?在Host表(或Group表)指定中間表的實例,加上backref就不用在Group表中指定
1 #聲明表的映射關系 2 class Host(Base): 3 __tablename__ = 'host' #表名 4 id = Column(Integer, primary_key=True, autoincrement=True) #默認自增 5 hostname = Column(String(64), unique=True, nullable=False) 6 ip_addr = Column(String(128), unique=True, nullable=False) 7 port = Column(Integer, default=22) 8 #外鍵關聯,主機與組名關聯 9 #group_id = Column(Integer, ForeignKey("group.id")) 10 groups = relationship("Group", #關聯Group表 11 secondary = Host2Group, #關聯第三方表 12 backref = "host_list") #雙向關聯,不用在Group類中再加這句代碼 13 14 def __repr__(self): 15 return "<id=%s,hostname=%s,ip_addr=%s>" % (self.id, 16 self.hostname, 17 self.ip_addr)3. 創建組與主機
1 if __name__ == '__main__': 2 SessionCls = sessionmaker(bind=engine) 3 session = SessionCls() 4 """ 5 g1 = Group(name = "g1") 6 g2 = Group(name = "g2") 7 g3 = Group(name = "g3") 8 g4 = Group(name = "g4") 9 session.add_all([g1,g2,g3,g4]) 10 """ 11 """ 12 h1 = Host(hostname="h1",ip_addr="10.1.1.1") 13 h2 = Host(hostname="h2",ip_addr="10.1.1.2",port=10000) 14 h3 = Host(hostname="h3",ip_addr="10.1.1.3",port=6666) 15 session.add_all([h1,h2,h3]) 16 """4. 建立關聯與查詢
1 """ 2 groups = session.query(Group).all() 3 h1 = session.query(Host).filter(Host.hostname=="h1").first() 4 h1.groups = groups #將h1關聯到所有的組 5 print("-->:",h1.groups) 6 h1.groups.pop() #刪除一個關聯 7 """ 8 h2 = session.query(Host).filter(Host.hostname=="h2").first() 9 #h2.groups = groups[1:-1] #將h2關聯到組(2和3) 10 print("=======>h2.groups:",h2.groups) 11 #=======>h2.groups: [<__main__.Group object at 0x00000000044A3F98>, 12 # <__main__.Group object at 0x00000000044A3FD0>] 13 #加上__repr__()后,變為=======>h2.groups: [<id=2,name=g2>, <id=3,name=g3>] 14 15 g1 = session.query(Group).first() 16 print("=======>g1:",g1.host_list) 17 #=======>g1: [<id=1,hostname=h1,ip_addr=10.1.1.1>] 18 session.commit()測試截圖:
查看表結構:
查看表內容:
查看第三方表:
?
完整例子:
1 from sqlalchemy import create_engine,func,Table 2 from sqlalchemy.ext.declarative import declarative_base 3 from sqlalchemy import Column, Integer, String,ForeignKey 4 from sqlalchemy.orm import sessionmaker,relationship 5 6 Base = declarative_base() # 生成一個SqlORM 基類(已經封閉metadata) 7 #echo=True可以查看創建表的過程 8 engine = create_engine("mysql+pymysql://root:root@localhost:3306/zcl", echo=True) 9 10 11 #直接創建表并返回表的實例 Host2Group主動關聯Host與Group(被關聯) 12 Host2Group = Table('host_to_group',Base.metadata, 13 Column('host_id',ForeignKey('host.id'),primary_key=True), 14 Column('group_id',ForeignKey('group.id'),primary_key=True), 15 #一個表為什么能創建兩個主鍵(其實是兩個列同時作為主鍵,非空且唯一) 16 #PRIMARY KEY (host_id, group_id), 17 ) 18 19 20 #聲明表的映射關系 21 class Host(Base): 22 __tablename__ = 'host' #表名 23 id = Column(Integer, primary_key=True, autoincrement=True) #默認自增 24 hostname = Column(String(64), unique=True, nullable=False) 25 ip_addr = Column(String(128), unique=True, nullable=False) 26 port = Column(Integer, default=22) 27 #外鍵關聯,主機與組名關聯 28 #group_id = Column(Integer, ForeignKey("group.id")) 29 groups = relationship("Group", #關聯Group表 30 secondary = Host2Group, #關聯第三方表 31 backref = "host_list")#雙向關聯,不用在Group類中再加這句代碼 32 33 def __repr__(self): 34 return "<id=%s,hostname=%s,ip_addr=%s>" % (self.id, 35 self.hostname, 36 self.ip_addr) 37 38 class Group(Base): 39 __tablename__ = "group" 40 id = Column(Integer,primary_key=True) 41 name = Column(String(64), unique=True, nullable=False) 42 43 def __repr__(self): 44 return "<id=%s,name=%s>" % (self.id, self.name) 45 46 47 Base.metadata.create_all(engine) # 創建所有表結構 48 49 if __name__ == '__main__': 50 SessionCls = sessionmaker(bind=engine) 51 session = SessionCls() 52 """ 53 g1 = Group(name = "g1") 54 g2 = Group(name = "g2") 55 g3 = Group(name = "g3") 56 g4 = Group(name = "g4") 57 session.add_all([g1,g2,g3,g4]) 58 """ 59 """ 60 h1 = Host(hostname="h1",ip_addr="10.1.1.1") 61 h2 = Host(hostname="h2",ip_addr="10.1.1.2",port=10000) 62 h3 = Host(hostname="h3",ip_addr="10.1.1.3",port=6666) 63 session.add_all([h1,h2,h3]) 64 """ 65 """ 66 groups = session.query(Group).all() 67 h1 = session.query(Host).filter(Host.hostname=="h1").first() 68 h1.groups = groups #將h1關聯到所有的組 69 print("-->:",h1.groups) 70 h1.groups.pop() #刪除一個關聯 71 """ 72 h2 = session.query(Host).filter(Host.hostname=="h2").first() 73 #h2.groups = groups[1:-1] 74 print("=======>h2.groups:",h2.groups) 75 #=======>h2.groups: [<__main__.Group object at 0x00000000044A3F98>, 76 # <__main__.Group object at 0x00000000044A3FD0>] 77 #加上__repr__()后,變為=======>h2.groups: [<id=2,name=g2>, <id=3,name=g3>] 78 79 g1 = session.query(Group).first() 80 print("=======>g1:",g1.host_list) 81 #=======>g1: [<id=1,hostname=h1,ip_addr=10.1.1.1>] 82 session.commit() View Code?
轉發注明出處:?http://www.cnblogs.com/0zcl/p/6504696.html?
總結
以上是生活随笔為你收集整理的python之SQLAlchemy ORM的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringMVC默认欢迎页面的问题
- 下一篇: Git命令集之八——提交命令