搜尋
首頁後端開發Python教學python之SQLAlchemy ORM範例介紹

一、ORM介紹

orm英文全名為object relational mapping,就是對象映射關係程序,簡單來說我們類似python這種面向對象的程序來說一切皆對象,但是我們使用的資料庫卻都是關係型的,為了確保一致的使用習慣,透過orm將程式語言的物件模型和資料庫的關係模型建立映射關係,這樣我們在使用程式語言對資料庫進行操作的時候可以直接使用程式語言的物件模型進行操作就可以了,而不用直接使用sql語言。

python之SQLAlchemy  ORM示例介绍

orm的優點:

  • #隱藏了資料存取細節,「封閉」的通用資料庫交互,ORM的核心。他讓我們的通用資料庫互動變得簡單易行,完全不用考慮該死的SQL語句。快速開發,由此而來。

  • ORM讓我們建構固化資料結構變得簡單易行。

缺點:

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

 

二、SQLAlchemy框架與資料庫API

在Python中,最有名的ORM架構是SQLAlchemy。使用者包含openstack\Dropbox等知名公司或應用,主要使用者清單http://www.php.cn/

python之SQLAlchemy  ORM示例介绍

需要自己把資料庫中的表格對應成類,然後才能透過物件的方式去呼叫。 SQLAlchemy不只可以支援MYSQL,還可以支援Oracle等。

Dialect用於和資料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...]

安裝SQLAlchemy:

pip install SQLAlchemy

 

三、連接資料庫並查詢

from sqlalchemy import create_engine

#连接数据库,生成engine对象;最大连接数为5个
engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/zcl", max_overflow=5)
print(engine)   #Engine(mysql+pymysql://root:***@127.0.0.1:3306/zcl)
result = engine.execute(&#39;select * from students&#39;) #不用commit(),会自动commit
print(result.fetchall())

輸出:

#
Engine(mysql+pymysql://root:***@127.0.0.1:3306/zcl)[(1, &#39;zcl&#39;, &#39;man&#39;, 22, &#39;15622341234&#39;, None), (2, &#39;alex&#39;, &#39;man&#39;, 30, &#39;15622341235&#39;, None), (5, &#39;Jack&#39;, &#39;man&#39;, 25, &#39;1351234&#39;, &#39;CN&#39;), (6, &#39;Mary&#39;, &#39;female&#39;, 18, &#39;1341234&#39;, &#39;USA&#39;), (10, &#39;Jack&#39;, &#39;man&#39;, 25, &#39;1351234&#39;, &#39;CN&#39;), (11, &#39;Jack2&#39;, &#39;man&#39;, 25, &#39;1351234&#39;, &#39;CN&#39;), (12, &#39;Mary&#39;, &#39;female&#39;, 18, &#39;1341234&#39;, &#39;USA&#39;), (13, &#39;cjy&#39;, &#39;man&#39;, 18, &#39;1562234&#39;, &#39;USA&#39;), (14, &#39;cjy2&#39;, &#39;man&#39;, 18, &#39;1562235&#39;, &#39;USA&#39;), (15, &#39;cjy3&#39;, &#39;man&#39;, 18, &#39;1562235&#39;, &#39;USA&#39;), (16, &#39;cjy4&#39;, &#39;man&#39;, 18, &#39;1562235&#39;, &#39;USA&#39;), (17, &#39;cjy5&#39;, &#39;man&#39;, 18, &#39;1562235&#39;, &#39;USA&#39;)]

 

四、建立表格

建立user與color表: 建立表格時需要與MetaData的實例綁定。

from sqlalchemy import create_engine, \
    Table, Column, Integer, String, MetaData, ForeignKey

metadata = MetaData()  #相当于实例一个父类

user = Table(&#39;user&#39;, metadata,      #相当于让Table继承metadata类
             Column(&#39;id&#39;, Integer, primary_key=True),
             Column(&#39;name&#39;, String(20)),
             )

color = Table(&#39;color&#39;, metadata,    #表名color
              Column(&#39;id&#39;, Integer, primary_key=True),
              Column(&#39;name&#39;, String(20)),
              )
engine = create_engine("mysql+pymysql://root:root@localhost:3306/zcl", max_overflow=5)

metadata.create_all(engine)  #table已经与metadate绑定

查看已建立的表格:

python之SQLAlchemy  ORM示例介绍

 

五、增刪改查

#1. 先來了解下原生sql語句的增刪改查:

from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey,select

metadata = MetaData()

user = Table(&#39;user&#39;, metadata,
             Column(&#39;id&#39;, Integer, primary_key=True),
             Column(&#39;name&#39;, String(20)),
             )

color = Table(&#39;color&#39;, metadata,
              Column(&#39;id&#39;, Integer, primary_key=True),
              Column(&#39;name&#39;, String(20)),
              )
engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/zcl", max_overflow=5)

conn = engine.connect()  #创建游标,当前实例所处状态

# 创建SQL语句,INSERT INTO "user" (id, name) VALUES (:id, :name)
#id号可省略,默认是自增的
# conn.execute(user.insert(), {&#39;id&#39;: 1, &#39;name&#39;: &#39;zcl&#39;})
# conn.close()

# sql = user.insert().values(name=&#39;wu&#39;)  #插入
# conn.execute(sql)
# conn.close()

#删除id号大于1的行,也可以where(user.c.name=="zcl")
# sql = user.delete().where(user.c.id > 1)
# conn.execute(sql)
# conn.close()

# 将name=="wuu"更改为"name=="ed"
# sql = user.update().where(user.c.name == &#39;wuu&#39;).values(name=&#39;ed&#39;)
# conn.execute(sql)
# conn.close()

#查询  下面不能写 sql = user.select... 会曝错
#sql = select([user, ])  #[(1, &#39;zcl&#39;), (9, &#39;ed&#39;), (10, &#39;ed&#39;)]
# sql = select([user.c.id, ])   #[(1,), (9,), (10,)]
sql = select([user.c.name, color.c.name]).where(user.c.id==color.c.id)
# sql = select([user.c.name]).order_by(user.c.name)
# sql = user.select([user]).group_by(user.c.name)

result = conn.execute(sql)
print(result.fetchall())
conn.close()

2. 透過SQLAlchemy的增刪改查(重要):

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column,Integer,String
from sqlalchemy.orm import sessionmaker

Base = declarative_base()    #生成一个SqlORM基类(已经封装metadata)
#echo=True可以查看创建表的过程
engine = create_engine("mysql+pymysql://root:root@localhost:3306/zcl", echo=True)

class Host(Base):
    __tablename__ = 'hosts'   #表名为host
    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)


Base.metadata.create_all(engine)   #创建所有表结构

if __name__ == '__main__':
    #创建与数据库的会话sessionclass,注意,这里返回给session的是个class类,不是实例
    SessionCls=sessionmaker(bind=engine)
    session=SessionCls()  #连接的实例
    #准备插入数据
    h1 = Host(hostname='localhost', ip_addr='127.0.0.1')    #实例化(未创建)
    h2 = Host(hostname='ubuntu', ip_addr='192.168.2.243', port=20000)
    
    #session.add(h1)   #也可以用下面的批量处理
    #session.add_all([h1,h2])
    #h2.hostname='ubuntu_test'  #只要没提交,此时修改也没问题
    
    #查询数据,返回一个对象
    obj = session.query(Host).filter(Host.hostname=="localhost").first()
    print("-->",obj)
    #[<__main__.hostobjectat0x00000000048dc0b8>]如果上面为.all()
    #<__main__.hostobjectat0x000000000493c208>如果上面为.first()
    
    #如果用.all(),会曝错AttributeError:'list'objecthasnoattribute'hostname'
    #obj.hostname = "localhost_1"   #将主机名修改为localhost_1
    
    session.delete(obj) #删除行
    
    session.commit()#提交</__main__.hostobjectat0x000000000493c208></__main__.hostobjectat0x00000000048dc0b8>

操作結果截圖:

python之SQLAlchemy  ORM示例介绍

六、外鍵關聯

1. 建立主機表hosts與分組表group,並建立關聯,即一個群組可對應多個主機:

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String,ForeignKey
from sqlalchemy.orm import sessionmaker,relationship

Base = declarative_base()  # 生成一个SqlORM 基类(已经封闭metadata)
#echo=True可以查看创建表的过程
engine = create_engine("mysql+pymysql://root:root@localhost:3306/zcl", echo=True)

class Host(Base):
    __tablename__ = &#39;hosts&#39;   #表名
    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"))


class Group(Base):
    __tablename__ = "group"
    id = Column(Integer,primary_key=True)
    name = Column(String(64), unique=True, nullable=False)


Base.metadata.create_all(engine)  # 创建所有表结构

if __name__ == &#39;__main__&#39;:
    # 创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例
    SessionCls = sessionmaker(bind=engine)
    session = SessionCls()  #连接的实例

    session.commit() #提交

查看結果:

python之SQLAlchemy  ORM示例介绍

 

問題: 查看新建的group表結構或從group表查詢會發現desc group;select * from group都會曝錯!!(為什麼會產生這種錯誤可能是group與資料庫有某些關聯導致的,eg:group by... 我猜的)

解決方法: 用desc zcl.group; select * from zcl.group;  (zcl為資料庫名稱)

python之SQLAlchemy  ORM示例介绍

 

2. 建立完表後就要在表格中建立資料啦。接下來在hosts表與group表建立資料:

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

Base = declarative_base()  # 生成一个SqlORM 基类(已经封闭metadata)
#echo=True可以查看创建表的过程
engine = create_engine("mysql+pymysql://root:root@localhost:3306/zcl", echo=True)

class Host(Base):
    __tablename__ = &#39;hosts&#39;   #表名
    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"))


class Group(Base):
    __tablename__ = "group"
    id = Column(Integer,primary_key=True)
    name = Column(String(64), unique=True, nullable=False)

Base.metadata.create_all(engine)  # 创建所有表结构

if __name__ == &#39;__main__&#39;:
    # 创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例
    SessionCls = sessionmaker(bind=engine)
    session = SessionCls()  #连接的实例

    g1 = Group(name = "g1")
    g2 = Group(name = "g2")
    g3 = Group(name = "g3")
    g4 = Group(name = "g4")
    session.add_all([g1,g2,g3,g4])

    #此时上面的g1,g2,g3三条记录还未存在,因为程序运行到这一行时还未commit(),故g1.id也未存在,但是下面一行代码是用到g1.id的!!经过测试: 运行时虽然不曝错,但关联不成功,如下图
    h1 = Host(hostname=&#39;localhost&#39;, ip_addr=&#39;127.0.0.1&#39;,group_id=g1.id)
    session.add(h1)

    session.commit() #提交

經過測試: 運行時雖然不曝錯,但關聯不成功,如下圖:

python之SQLAlchemy  ORM示例介绍

# # 

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:&#39;Host&#39;object has no attribute &#39;group&#39;

嗯,你是初学者,你当然会说通过过h.group.name就可以找到与主机关联的组名! BUT,这是不行的,会曝错,因为Host类根本就没有group属性!!

解决方法:

  • first:

from sqlalchemy.orm import relationship       #导入relationship

  • second:

在Host类中加入group = relationship("Group"):

class Host(Base):    __tablename__ = &#39;hosts&#39;   #表名
    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");

class Host(Base):
    __tablename__ = &#39;hosts&#39;   #表名
    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")

class Group(Base):
    __tablename__ = "group"
    id = Column(Integer, primary_key=True)
    name = Column(String(64), unique=True, nullable=False)
    hosts = relationship("Host")

Base.metadata.create_all(engine)     #创建所有表结构

g4 = session.query(Group).filter(Group.name=="g4").first()
h = session.query(Host).filter(Host.hostname=="localhost").first()
print("h1:",h.group_id)       #h1: 4
#此时可以获取已经关联的group_id,但如何获取已关联的组的组名
print(h.group.name)          #g4
print("g4:",g4.hosts)        #g4:[<__main__.Hostobjectat0x0000000004303860>]

 

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

python之SQLAlchemy  ORM示例介绍

关于join的原生sql操作:

python之SQLAlchemy  ORM示例介绍

python之SQLAlchemy  ORM示例介绍

 

在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命令,进行分类聚合。

具体请看下图:

python之SQLAlchemy  ORM示例介绍

python之SQLAlchemy  ORM示例介绍

对应SQLAlchemy语句:

obj1 = session.query(Host).join(Host.group).group_by(Group.name).all()    #分类聚合
print("-->obj1:",obj1)

 

python之SQLAlchemy  ORM示例介绍

对应SQLAlchemy语句:

obj2 = session.query(Host,func.count(Group.name)).join(Host.group).group_by(Group.name).all()
print("-->obj2:",obj2)

输出:
-->obj2: [(<__main__.host>, 1), (<__main__.host>, 2)]</__main__.host></__main__.host>

 

十、多对多关联

多对多关联,即: 一个主机h1可对应在多个组(g1,g2),一个组(g1)可对应多个主机(h1,h2)

想实现如下的多对多关联,需要一张中间表。Eg:
 h1   g1
 h1   g2
 h2   g1

Host表
 h1
 h2
 h3
Group表
 g1 
 g2
 g3

HostToGroup中间表(实现多对多关联,sqlalchemy也是这样实现的)
 id    host_id     group_id  1       1            1
  2       1            2
  3       2            1

虽然有了中间表,但如果想查看一个组对应的所有主机名或者一个主机对应的所有组,还是需要Group/Host与中间表进行一系列的关联操作(join~), 但SqlAlchemy简化了关联操作!!

调用下面命令便会自动关联中间表:

Host.groups()  #查看一个主机对应所有组
Group.hosts()

 

SQLAlchemy是如何实现多对多关联的??

1. 建立中间表,关联其它两个表

from sqlalchemy import create_engine,func,Table
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String,ForeignKey
from sqlalchemy.orm import sessionmaker,relationship

Base = declarative_base()  # 生成一个SqlORM 基类(已经封闭metadata)
#echo=True可以查看创建表的过程
engine = create_engine("mysql+pymysql://root:root@localhost:3306/zcl", echo=True)


#直接创建表并返回表的实例  Host2Group主动关联Host与Group(被关联)
Host2Group = Table('host_to_group',Base.metadata,
    Column('host_id',ForeignKey('host.id'),primary_key=True),
    Column('group_id',ForeignKey('group.id'),primary_key=True),
    #一个表为什么能创建两个主键(其实是两个列同时作为主键,非空且唯一)
    #PRIMARY KEY (host_id, group_id),
)

2. 在Host表(或Group表)指定中间表的实例,加上backref就不用在Group表中指定

#声明表的映射关系
class Host(Base):
    __tablename__ = 'host'   #表名
    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"))
    groups = relationship("Group",                #关联Group表
                           secondary = Host2Group, #关联第三方表
                           backref = "host_list") #双向关联,不用在Group类中再加这句代码

    def __repr__(self):
        return "<id>" % (self.id,
                                                        self.hostname,
                                                        self.ip_addr)</id>

3. 创建组与主机

if __name__ == '__main__':
    SessionCls = sessionmaker(bind=engine)
    session = SessionCls()
    """
    g1 = Group(name = "g1")
    g2 = Group(name = "g2")
    g3 = Group(name = "g3")
    g4 = Group(name = "g4")
    session.add_all([g1,g2,g3,g4])
    """
    """
    h1 = Host(hostname="h1",ip_addr="10.1.1.1")
    h2 = Host(hostname="h2",ip_addr="10.1.1.2",port=10000)
    h3 = Host(hostname="h3",ip_addr="10.1.1.3",port=6666)
    session.add_all([h1,h2,h3])
    """

4. 建立关联与查询

"""
    groups = session.query(Group).all()
    h1 = session.query(Host).filter(Host.hostname=="h1").first()
    h1.groups = groups    #将h1关联到所有的组
    print("-->:",h1.groups)
    h1.groups.pop()   #删除一个关联
    """
    h2 = session.query(Host).filter(Host.hostname=="h2").first()
    #h2.groups = groups[1:-1]   #将h2关联到组(2和3)
    print("=======>h2.groups:",h2.groups)
    #=======>h2.groups: [<__main__.group>,
    #  <__main__.group>]
    #加上__repr__()后,变为=======>h2.groups: [<id>, <id>]

    g1 = session.query(Group).first()
    print("=======>g1:",g1.host_list)
    #=======>g1: [<id>]
    session.commit()</id></id></id></__main__.group></__main__.group>

测试截图:

查看表结构:

python之SQLAlchemy  ORM示例介绍

查看表内容:

python之SQLAlchemy  ORM示例介绍

查看第三方表:

python之SQLAlchemy  ORM示例介绍

 

完整例子:

from sqlalchemy import create_engine,func,Table
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String,ForeignKey
from sqlalchemy.orm import sessionmaker,relationship

Base = declarative_base()  # 生成一个SqlORM 基类(已经封闭metadata)
#echo=True可以查看创建表的过程
engine = create_engine("mysql+pymysql://root:root@localhost:3306/zcl", echo=True)


#直接创建表并返回表的实例  Host2Group主动关联Host与Group(被关联)
Host2Group = Table('host_to_group',Base.metadata,
    Column('host_id',ForeignKey('host.id'),primary_key=True),
    Column('group_id',ForeignKey('group.id'),primary_key=True),
    #一个表为什么能创建两个主键(其实是两个列同时作为主键,非空且唯一)
    #PRIMARY KEY (host_id, group_id),
)


#声明表的映射关系
class Host(Base):
    __tablename__ = 'host'   #表名
    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"))
    groups = relationship("Group",                #关联Group表
                           secondary = Host2Group, #关联第三方表
                           backref = "host_list")#双向关联,不用在Group类中再加这句代码

    def __repr__(self):
        return "" % (self.id,
                                                        self.hostname,
                                                        self.ip_addr)

class Group(Base):
    __tablename__ = "group"
    id = Column(Integer,primary_key=True)
    name = Column(String(64), unique=True, nullable=False)

    def __repr__(self):
        return "" % (self.id, self.name)


Base.metadata.create_all(engine)  # 创建所有表结构

if __name__ == '__main__':
    SessionCls = sessionmaker(bind=engine)
    session = SessionCls()
    """
    g1 = Group(name = "g1")
    g2 = Group(name = "g2")
    g3 = Group(name = "g3")
    g4 = Group(name = "g4")
    session.add_all([g1,g2,g3,g4])
    """
    """
    h1 = Host(hostname="h1",ip_addr="10.1.1.1")
    h2 = Host(hostname="h2",ip_addr="10.1.1.2",port=10000)
    h3 = Host(hostname="h3",ip_addr="10.1.1.3",port=6666)
    session.add_all([h1,h2,h3])
    """
    """
    groups = session.query(Group).all()
    h1 = session.query(Host).filter(Host.hostname=="h1").first()
    h1.groups = groups  #将h1关联到所有的组
    print("-->:",h1.groups)
    h1.groups.pop()   #删除一个关联
    """
    h2 = session.query(Host).filter(Host.hostname=="h2").first()
    #h2.groups = groups[1:-1]
    print("=======>h2.groups:",h2.groups)
    #=======>h2.groups: [<__main__.group>,
    #  <__main__.group>]
    #加上__repr__()后,变为=======>h2.groups: []

    g1 = session.query(Group).first()
    print("=======>g1:",g1.host_list)
    #=======>g1: []
    session.commit()

更多python之SQLAlchemy  ORM示例介绍相关文章请关注PHP中文网!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Python的混合方法:編譯和解釋合併Python的混合方法:編譯和解釋合併May 08, 2025 am 12:16 AM

pythonuseshybridapprace,ComminingCompilationTobyTecoDeAndInterpretation.1)codeiscompiledtoplatform-Indepententbybytecode.2)bytecodeisisterpretedbybythepbybythepythonvirtualmachine,增強效率和通用性。

了解python的' for”和' then”循環之間的差異了解python的' for”和' then”循環之間的差異May 08, 2025 am 12:11 AM

theKeyDifferencesBetnewpython's“ for”和“ for”和“ loopsare:1)” for“ loopsareIdealForiteringSequenceSquencesSorkNowniterations,而2)”,而“ loopsareBetterforConterContinuingUntilacTientInditionIntionismetismetistismetistwithOutpredefinedInedIterations.un

Python串聯列表與重複Python串聯列表與重複May 08, 2025 am 12:09 AM

在Python中,可以通過多種方法連接列表並管理重複元素:1)使用 運算符或extend()方法可以保留所有重複元素;2)轉換為集合再轉回列表可以去除所有重複元素,但會丟失原有順序;3)使用循環或列表推導式結合集合可以去除重複元素並保持原有順序。

Python列表串聯性能:速度比較Python列表串聯性能:速度比較May 08, 2025 am 12:09 AM

fasteStmethodMethodMethodConcatenationInpythondependersonListsize:1)forsmalllists,operatorseffited.2)forlargerlists,list.extend.extend()orlistComprechensionfaster,withextendEffaster,withExtendEffers,withextend()withextend()是extextend()asmoremory-ememory-emmoremory-emmoremory-emmodifyinginglistsin-place-place-place。

您如何將元素插入python列表中?您如何將元素插入python列表中?May 08, 2025 am 12:07 AM

toInSerteLementIntoApythonList,useAppend()toaddtotheend,insert()foreSpificPosition,andextend()formultiplelements.1)useappend()foraddingsingleitemstotheend.2)useAddingsingLeitemStotheend.2)useeapecificindex,toadapecificindex,toadaSpecificIndex,toadaSpecificIndex,blyit'ssssssslorist.3 toaddextext.3

Python是否列表動態陣列或引擎蓋下的鏈接列表?Python是否列表動態陣列或引擎蓋下的鏈接列表?May 07, 2025 am 12:16 AM

pythonlistsareimplementedasdynamicarrays,notlinkedlists.1)他們areStoredIncoNtiguulMemoryBlocks,mayrequireRealLealLocationWhenAppendingItems,EmpactingPerformance.2)LinkesedlistSwoldOfferefeRefeRefeRefeRefficeInsertions/DeletionsButslowerIndexeDexedAccess,Lestpypytypypytypypytypy

如何從python列表中刪除元素?如何從python列表中刪除元素?May 07, 2025 am 12:15 AM

pythonoffersFourmainMethodStoreMoveElement Fromalist:1)刪除(值)emovesthefirstoccurrenceofavalue,2)pop(index)emovesanderturnsanelementataSpecifiedIndex,3)delstatementremoveselemsbybybyselementbybyindexorslicebybyindexorslice,and 4)

試圖運行腳本時,應該檢查是否會遇到'權限拒絕”錯誤?試圖運行腳本時,應該檢查是否會遇到'權限拒絕”錯誤?May 07, 2025 am 12:12 AM

toresolvea“ dermissionded”錯誤Whenrunningascript,跟隨台詞:1)CheckAndAdjustTheScript'Spermissions ofchmod xmyscript.shtomakeitexecutable.2)nesureThEseRethEserethescriptistriptocriptibationalocatiforecationAdirectorywherewhereyOuhaveWritePerMissionsyOuhaveWritePermissionsyYouHaveWritePermissions,susteSyAsyOURHomeRecretectory。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器