在前两部分的学习笔记中,讲了model类的建立与表的创建以及通过flask-migrate对数据库进行迁移。本篇继续,开始实际演示对数据进行操作。
以下示例基于Part01中的model类
一对一关系
在model中 Account 与 Profile之间是一对一关系
class Account(Base):
__tablename__ = "accounts"
account_name = db.Column(db.String(50), unique=True, nullable=False)
account_email = db.Column(db.String(120), unique=True, nullable=False)
# 与Profile建立一对一关系
profile = db.relationship('Profile', backref='account', uselist=False)
def __init__(self, account_name, account_email):
self.account_name = account_name
self.account_email = account_email
服务器托管网
def __repr__(self):
return '' % self.account_name, self.account_email
class Profile(Base):
__tablename__ = "profiles"
fullname = db.Column(db.String(100))
gender = db.Column(db.String(10))
# 外键
account_id = db.Column(db.Integer, db.ForeignKey('accounts.id'), unique=True)
def __init__(self, fullname, gender):
self.fullname = fullname
self.gender = gender
def __repr__(self):
return '' % self.fullname, self.gender
可以通过创建对象,然后通过对应的类属性来创建关联。
data_1v1.py
# 导入需要使用的模型和数据库实例
from model import Account, Profile, Project, Host, db
from app import app
# 在 Flask 应用上下文中执行以下代码
with app.app_context():
# 分别创建三个 Account 对象和三个 Profile 对象
a1 = Account(account_name='lisi', account_email='a1@123.com')
a2 = Account('xiaoni', 'a2@123.com')
pf1 = Profile(fullname='里斯', gender='M')
pf2 = Profile('小妮', 'F')
# 由于在 model 中定义了这两个类的 relationship,并使用了 backref,
# 所以这两个类的对象有相应的属性进行关联,
# Account 类对象可以使用 profile 属性来获取 Profile 对象,
# 同理,Profile 类对象可以使用 account 属性来获取 Account 对象。
a1.profile = pf1
pf2.account = a2
# 将对象添加到数据库会话中
db.session.add(a1)
db.session.add(a2)
db.session.add(pf1)
db.session.add(pf2)
# 提交更改到数据库
db.session.commit()
# 通过查询获取 Account 对象
q_a1 = Account.query.filter_by(account_name='lisi').first()
# 打印查询结果
print('q_a1')
print(q_a1.account_name, q_a1.account_email, q_a1.profile.fullname, q_a1.profile.gender)
直接执行上述代码可以得到结果
上述代码定义a1、a2 两个Account对象,pf1、pf2两个Profile对象,通过为各自属性赋值来实现relationship的关联,然后提交更改到数据库
一对多关系
在model中 Project与Host之间是一对多关系
注意:可以通过替换lazy的值来看查看不同返回,具体参考本系列文档的Part01
# 一对多关系
class Project(Base):
__tablename__ = "projects"
project_name = db.Column(db.String(50), unique=True, nullable=False)
project_webhook = db.Column(db.String(150))
# 与Host建立一对多关系
hosts = db.relationship('Host', backref='project', lazy=True)
# 与Accounts通过中间表建立多对多关系
accounts = db.relationship('Account', secondary='account_project', backref=db.backref('projects', lazy=True))
def __init__(self, project_name, project_webhook):
self.project_name = project_name
self.project_webhook = project_webhook
def __repr__(self):
return '' % self.project_name, self.project_webhook
class Host(Base):
__tablename__ = "hosts"
hostname = db.Column(db.String(50))
ip = db.Column(db.String(15))
project_id = db.Column(db.Integer, db.ForeignKey('projects.id'))
def __init__(self, hostname, ip):
self.hostname = hostname
self.ip = ip
def __repr__(self):
return '' % self.hostname, self.ip
同样的示例
data_1vm.py
from model import Account, Profile, Project, Host, db
from app import app
# 在 Flask 应用上下文中执行以下代码
with app.app_context():
# 创建两个Project对象,四个Host对象,并关联
p1 = Project(project_name='p1', project_webhook='http://xxx.com/webhook')
p2 = Project('p2', 'http://xxx.com/webhook')
h1 = Host(hostname='h1', ip='127.0.0.1')
h2 = Host('h2', '127.0.0.2')
h3 = Host(hostname='h3', ip='127.0.0.3')
h4 = Host('h4', '127.0.0.4')
# 建立关联关系,p1与h1 h2建立关联,p2与h3 h4建立关联
# 从两个方向进行关联
p1.hosts.append(h1)
p1.hosts.append(h2)
h3.project = p2
#服务器托管网 h4这种通过外键方式进行管理,理论上是可以的,
# 但是由于被关联对象p2还没有提交到数据库,所以关联的结果只会是一个寂寞。
# h4.project_id = p2.id
db.session.add(p1)
db.session.add(p2)
db.session.add(h1)
db.session.add(h2)
db.session.add(h3)
db.session.add(h4)
# 提交更改到数据库
db.session.commit()
q_p1 = Project.query.filter_by(project_name='p1').first()
print('q_p1')
print(q_p1.project_name, q_p1.project_webhook)
p1_host = q_p1.hosts
print('与P1关联的Host')
for h in p1_host:
print(h.hostname, h.ip)
print("~~~~~~~~~~~")
q_p2 = Project.query.filter_by(project_name='p2').first()
print('q_p2')
print(q_p2.project_name, q_p2.project_webhook)
print('与P2关联的Host')
p2_host = q_p2.hosts
for h in p2_host:
print(h.hostname, h.ip)
直接执行上述代码可以得到结果
多对多关系
在model中 Account与之间多对多关系。
注意:可以通过替换lazy的值来看查看不同返回,具体参考本系列文档的Part01
class Account(Base):
__tablename__ = "accounts"
account_name = db.Column(db.String(50), unique=True, nullable=False)
account_email = db.Column(db.String(120), unique=True, nullable=False)
# 与Profile建立一对一关系
profile = db.relationship('Profile', backref='account', uselist=False)
def __init__(self, account_name, account_email):
self.account_name = account_name
self.account_email = account_email
def __repr__(self):
return '' % self.account_name, self.account_email
class Project(Base):
__tablename__ = "projects"
project_name = db.Column(db.String(50), unique=True, nullable=False)
project_webhook = db.Column(db.String(150))
# 与Host建立一对多关系
hosts = db.relationship('Host', backref='project', lazy=True)
# 与Accounts通过中间表建立多对多关系
accounts = db.relationship('Account', secondary='account_project', backref=db.backref('projects', lazy=True))
def __init__(self, project_name, project_webhook):
self.project_name = project_name
self.project_webhook = project_webhook
def __repr__(self):
return '' % self.project_name, self.project_webhook
# 多对多关系
account_project = db.Table(
'account_project',
db.Column('account_id', db.Integer, db.ForeignKey('accounts.id')),
db.Column('project_id', db.Integer, db.ForeignKey('projects.id'))
)
data_mvm.py
from model import Account, Profile, Project, Host, db
from app import app
# 在 Flask 应用上下文中执行以下代码
with app.app_context():
# 上文中已经在数据库中创建了两个Account和两个Project,这里直接读取出来
a1 = Account.query.filter_by(account_name="lisi").first()
a2 = Account.query.filter_by(account_name="xiaoni").first()
p1 = Project.query.filter_by(project_name="p1").first()
p2 = Project.query.filter_by(project_name="p2").first()
# 通过relationship进行关联
a1.projects = [p1, p2]
a2.projects = [p1]
db.session.commit()
q_a1 = Account.query.filter_by(account_name="lisi").first()
print(q_a1.account_name, q_a1.account_email)
print('关联的Project')
for p in q_a1.projects:
print(p.project_name, p.project_webhook)
print('project {} 关联的Host'.format(p.project_name))
for h in p.hosts:
print(h.hostname, h.ip)
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
q_p1 = Project.query.filter_by(project_name="p1").first()
print(q_p1.project_name, q_p1.project_webhook)
print('关联的Account')
for a in q_p1.accounts:
print(a.account_name, a.account_email)
未完待续:
marshmallow 的使用 序列化与反序列化
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
相关推荐: 使用Redis发布订阅模式实现 Session共享
其实并不是实现session共享,而是通过redis的发布订阅,让所有集群的服务器,都让自己的session发送一下消息。比如说userId在第35台服务器上, 有100台服务器,那么第1台服务器收到消息,需要通知userId,不是找到第35台服务器,而是通知…