Python SQLAlchemy

1.创建数据库

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_engine

engine = create_engine("mysql+pymysql://root:Passw0rd!@192.168.2.101/beadata", max_overflow=5)

Base = declarative_base()

class Test(Base):
    __tablename__ = 'Test'
    nid = Column(Integer,primary_key=True,autoincrement=True)
    name = Column(String(32))

class Group(Base):
    __tablename__ = 'Group'
    nid = Column(Integer,primary_key=True,autoincrement=True)
    caption = Column(String(32))

class User(Base):
    __tablename__ = 'User'
    nid = Column(Integer,primary_key=True,autoincrement=True)
    username = Column(String(32))
    group_id = Column(Integer,ForeignKey('Group.nid'))

def init_db():
    Base.metadata.create_all(engine)

# def drop_db():
#     Base.metadata.drop_all(engine)

init_db()

执行init_db创建一个数据库的对象(数据库必须存在),创建了上面的三张表。需要执行操作,要创建session

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

然后利用session来增加数据:

session.add(Group(caption='dba'))
session.add(Group(caption='dvd'))


session.add_all([
    User(username='alex4',group_id='4'),
    User(username='alex5',group_id='5'),
    User(username='alex6',group_id='6'),
])

session.commit()

插入的时候报键值对错误。

2.单表查询,得到的结果是一个列表的对象

ret = session.query(User).filter(User.username == 'alex1').all()
print (ret)
print (ret[0].nid,ret[0].username,ret[0].group_id)

[<__main__.User object at 0x000000000375CA20>]
1 alex1 1

需要注意的是,我们的ret返回的时候其实是一个列表的对象,那么如何能返回我们看到的数据呢?在SQLAlchemy中,我们定义了__repr__的方法,重写__repr__方法后,每次返回的就不是对象而是看到的数据了。

class User(Base):
    __tablename__ = 'User'
    nid = Column(Integer,primary_key=True,autoincrement=True)
    username = Column(String(32))
    group_id = Column(Integer,ForeignKey('Group.nid'))

    def __repr__(self):
        temp = "[%s --- %s --- %s]"%(self.nid,self.username,self.group_id)
        return temp

返回结果:

[[1 --- alex1 --- 1], [2 --- alex2 --- 2]]

3.一对多之正向查找与反向查找

我们设计两张表:

Group表:

nid caption
1 dba
2 dvd
3 sic

 User表:

nid username group_id
1 alex1 1
2 alex2 1
15 alex1 2
16 alex1 1

在数据中,JOIN操作得到的结果如下:

JOIN:
sql = session.query(User).join(Group)
print(sql)
ret = session.query(User).join(Group).all()
print (ret)
结果:
SELECT "User".nid AS "User_nid", "User".username AS "User_username", "User".group_id AS "User_group_id" 
FROM "User" JOIN "Group" ON "Group".nid = "User".group_id
[[1 --- alex1 --- 1], [2 --- alex2 --- 1], [15 --- alex1 --- 2], [16 --- alex1 --- 1]]

User LEFT JOIN Group

sql = session.query(User).join(Group,isouter=True)
print(sql)
ret = session.query(User).join(Group,isouter=True).all()
print (ret)
SELECT "User".nid AS "User_nid", "User".username AS "User_username", "User".group_id AS "User_group_id" 
FROM "User" LEFT OUTER JOIN "Group" ON "Group".nid = "User".group_id
[[1 --- alex1 --- 1], [2 --- alex2 --- 1], [15 --- alex1 --- 2], [16 --- alex1 --- 1]]

Group LEFT JOIN User

sql = session.query(Group,User.username).join(User,isouter=True)
print(sql)
ret = session.query(Group,User.username).join(User,isouter=True).all()
print (ret)

SELECT "Group".nid AS "Group_nid", "Group".caption AS "Group_caption", "User".username AS "User_username"
FROM "Group" LEFT OUTER JOIN "User" ON "Group".nid = "User".group_id
[([1 --- dba], 'alex1'), ([1 --- dba], 'alex2'), ([2 --- dvd], 'alex1'), ([3 --- sic], None)]

正向查找:

  传统形式下,我们要查找用户'alex2'属于哪个组,需要执行下面的命令:

ret = session.query(User.username,Group.caption).join(Group).filter(User.username == 'alex2').all()
print (ret)

执行结果:

[('alex2', 'dba')]

但在新方法下面:

ret = session.query(User).filter(User.username == 'alex2').all()
for obj in ret:
    print (obj.nid,obj.username,obj.group,obj.group.caption)

执行结果:

2 alex2 [1 --- dba] dba

原因在于,在'User'表中有如下的定义

 group = relationship("Group", backref='uuu')

表示的意思是在'User'表中隐性的添加了一列叫做'group',这一列表示的就是表中数据是属于'Group'中的那一个组的对应关系,它返回的是一个对象,因此可以使用obj.group.caption来访问'Group'中的数据。

=================================================================================================

反向查找:

  传统形式下,我们需要获取到'dba'这个角色的内容,需要执行下面的命令:

ret = session.query(User.username,Group.caption).join(Group,isouter=True).filter(Group.caption == 'dba').all()
print (ret)

执行结果:

[('alex1', 'dba'), ('alex2', 'dba'), ('alex1', 'dba')]

但是在新方法下面:

obj = session.query(Group).filter(Group.caption == 'dba').all()
for item in obj:
    print (item.uuu)

执行结果:

[[1 --- alex1 --- 1], [2 --- alex2 --- 1], [16 --- alex1 --- 1]]

原因在于,在于外键在同一个类的定义里面,有如下的说明:

class User(Base):
    __tablename__ = 'User'
    nid = Column(Integer,primary_key=True,autoincrement=True)
    username = Column(String(32))
    group_id = Column(Integer,ForeignKey('Group.nid'))
    group = relationship("Group", backref='uuu')

    def __repr__(self):
        temp = "[%s --- %s --- %s]"%(self.nid,self.username,self.group_id)
        return temp

这相当于定义了在User表中添加了一个字段为group,这个字段记录了用户对应的组,而'uuu'则相当于在表Group中每一行中添加了一个列表,内容是属于这个组的各个用户的数据。

原文地址:https://www.cnblogs.com/python-study/p/5889835.html