搜索
首页后端开发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)
    #[0255631d0cd3bd8030034003e6ba8089]如果上面为.all()
    #f8774803eaa8e8932442db37a173b2b9如果上面为.first()
    
    #如果用.all(),会曝错AttributeError:'list'objecthasnoattribute'hostname'
    #obj.hostname = "localhost_1"   #将主机名修改为localhost_1
    
    session.delete(obj) #删除行
    
    session.commit()#提交

操作结果截图:

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: [(eee7a277edacfa2db32c6af0fb3aa2a9, 1), (f4f7c97c04e3ddaa72fc606608f96c28, 2)]

 

十、多对多关联

多对多关联,即: 一个主机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 "f629f4ea386063e8614098b37acef85e" % (self.id,
                                                        self.hostname,
                                                        self.ip_addr)

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: [6e2fcbe3155f6068e5e0552abc854817,
    #  f1a29f8066407730d73efbdfa1665798]
    #加上__repr__()后,变为=======>h2.groups: [fba807bf0ed0cd82abe904d49adf340d, a9d37a5fcbc886fdd4000cb295264863]

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

测试截图:

查看表结构:

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 "f629f4ea386063e8614098b37acef85e" % (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 "5c798f716970eed1a3e59cce8a955665" % (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: [6e2fcbe3155f6068e5e0552abc854817,
    #  f1a29f8066407730d73efbdfa1665798]
    #加上__repr__()后,变为=======>h2.groups: [fba807bf0ed0cd82abe904d49adf340d, a9d37a5fcbc886fdd4000cb295264863]

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

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

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
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。

与Python的图像处理中如何使用阵列?与Python的图像处理中如何使用阵列?May 07, 2025 am 12:04 AM

ArraysarecrucialinPythonimageprocessingastheyenableefficientmanipulationandanalysisofimagedata.1)ImagesareconvertedtoNumPyarrays,withgrayscaleimagesas2Darraysandcolorimagesas3Darrays.2)Arraysallowforvectorizedoperations,enablingfastadjustmentslikebri

对于哪些类型的操作,阵列比列表要快得多?对于哪些类型的操作,阵列比列表要快得多?May 07, 2025 am 12:01 AM

ArraySaresificatificallyfasterthanlistsForoperationsBenefiting fromDirectMemoryAcccccccCesandFixed-Sizestructures.1)conscessingElements:arraysprovideconstant-timeaccessduetocontoconcotigunmorystorage.2)iteration:araysleveragececacelocality.3)

说明列表和数组之间元素操作的性能差异。说明列表和数组之间元素操作的性能差异。May 06, 2025 am 12:15 AM

ArraySareBetterForlement-WiseOperationsDuetofasterAccessCessCessCessCessCessAndOptimizedImplementations.1)ArrayshaveContiguucuulmemoryfordirectAccesscess.2)列出sareflexible butslible dueTopotentEnallymideNamicizing.3)forlarargedAtaTasetsetsetsetsetsetsetsetsetsetsetlib

如何有效地对整个Numpy阵列进行数学操作?如何有效地对整个Numpy阵列进行数学操作?May 06, 2025 am 12:15 AM

在NumPy中进行整个数组的数学运算可以通过向量化操作高效实现。 1)使用简单运算符如加法(arr 2)可对数组进行运算。 2)NumPy使用C语言底层库,提升了运算速度。 3)可以进行乘法、除法、指数等复杂运算。 4)需注意广播操作,确保数组形状兼容。 5)使用NumPy函数如np.sum()能显着提高性能。

您如何将元素插入python数组中?您如何将元素插入python数组中?May 06, 2025 am 12:14 AM

在Python中,向列表插入元素有两种主要方法:1)使用insert(index,value)方法,可以在指定索引处插入元素,但在大列表开头插入效率低;2)使用append(value)方法,在列表末尾添加元素,效率高。对于大列表,建议使用append()或考虑使用deque或NumPy数组来优化性能。

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

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中