PS:
1.实例包括一对一,一对多,多对多,以及自身的一对一,一对多,多对多
2.关于表的名字:__tablename__是表的名字,但是我们可以不设置,这样sqlalchemy会根据类名给予默认名,类名的大写字母在表名会变成下划线+小写字母(开头大写则,没有下划线),如WeChat类的默认表名是we_chat.但如果类名全是大写,则表名会和类名一样,像QQ类的默认表名就是QQ
3.实现多对多的关系需要中介表(类似图论里的边的含义),有一点注意的是中介类要写在那两个类之前,否则报错
一对一
微信和QQ的绑定是一对一的关系
一个微信只能绑定一个QQ
一个QQ只能绑定一个微信
class WeChat(db.Model):
id=db.Column(db.Integer,primary_key=True)
nickname=db.Column(db.String(80))
password=db.Column(db.String(120))
bing_qq=db.relationship('QQ',backref='bing_wechat',uselist=False)
class QQ(db.Model):
id=db.Column(db.Integer,primary_key=True)
nickname=db.Column(db.String(80))
password=db.Column(db.String(120))
wechat_id=db.Column(db.Integer,db.ForeignKey('we_chat.id'))
relationship和对方的id可以调转写
class WeChat(db.Model):
id=db.Column(db.Integer,primary_key=True)
nickname=db.Column(db.String(80))
password=db.Column(db.String(120))
qq_id=db.Column(db.Integer,db.ForeignKey('QQ.id'))
class QQ(db.Model):
id=db.Column(db.Integer,primary_key=True)
nickname=db.Column(db.String(80))
password=db.Column(db.String(120))
bing_wechat=db.relationship('WeChat',backref='bing_qq',uselist=False)
>>> q1=QQ(nickname='123',password='123456')
>>> w1=WeChat(nickname='jh',password='123456')
>>> q1.bing_wechat=w1
>>> db.session.add(q1)
>>> db.session.add(w1)
>>> db.session.commit()
>>> q1.bing_wechat.nickname
u'jh'
>>> w1.bing_qq.nickname
u'123'
>>>
一对多
博客用户和博文是一对多的关系
一个用户有多篇博文,而一篇博文只能有一个作者
id=db.Column(db.Integer,primary_key=True)
nickname=db.Column(db.String(80),unique=True)
password=db.Column(db.String(120))
posts=db.relationship('Post',backref='author',lazy='dynamic')
class Post(db.Model):
id=db.Column(db.Integer,primary_key=True)
title=db.Column(db.String(120),unique=True)
body=db.Column(db.Text)
user_id=db.Column(db.Integer,db.ForeignKey('user.id'))
relationship也可以写在post处
id=db.Column(db.Integer,primary_key=True)
nickname=db.Column(db.String(80),unique=True)
password=db.Column(db.String(120))
class Post(db.Model):
id=db.Column(db.Integer,primary_key=True)
title=db.Column(db.String(120),unique=True)
body=db.Column(db.Text)
user_id=db.Column(db.Integer,db.ForeignKey('user.id'))
author=db.relationship('User',backref='posts')
>>> u1=User(nickname='jh',password='123456')
>>> p1=Post(title='first',body='helloworld',author=u1)
>>> p2=Post(title='second',body='hello,JH',author=u1)
>>> db.session.add(u1)
>>> db.session.add(p1)
>>> db.session.add(p2)
>>> db.session.commit()
>>> u1.posts[0].title
u'first'
>>> u1.posts[1].title
u'second'
>>> for p in u1.posts:
... print p.title,p.body
...
first helloworld
second hello,JH
>>> p1.author.nickname
u'jh'
>>> p2.author.nickname
u'jh'
>>>
标签与博文之间的关系是多对多的关系
一个标签可以贴多篇博文
一篇博文也可以贴多个标签
#中介
post_tag=db.Table('post_tag',db.Column('tag_id',db.Integer,db.ForeignKey('tag.id')),
db.Column('post_id',db.Integer,db.ForeignKey('post.id')))
class Post(db.Model):
id=db.Column(db.Integer,primary_key=True)
title=db.Column(db.String(120),unique=True)
body=db.Column(db.Text)
tags=db.relationship('Tag',secondary=post_tag,backref='posts',lazy='dynamic')
class Tag(db.Model):
id=db.Column(db.Integer,primary_key=True)
name=db.Column(db.String(120),unique=True)
同样,relationship写在哪里都没所谓
db.Column('tag_id',db.Integer,db.ForeignKey('tag.id')),
db.Column('post_id',db.Integer,db.ForeignKey('post.id')))
class Post(db.Model):
id=db.Column(db.Integer,primary_key=True)
title=db.Column(db.String(120),unique=True)
body=db.Column(db.Text)
class Tag(db.Model):
id=db.Column(db.Integer,primary_key=True)
name=db.Column(db.String(120),unique=True)
posts=db.relationship('Post',secondary=post_tag,backref='tags',lazy='dynamic')
样例
>>> t1=Tag(name='python')>>> t2=Tag(name='sqlalchemy')
>>> p1=Post(title='str in python',body='...')
>>> p2=Post(title='many to many in flask-sqlalchemy',body='...')
>>> t1.posts.append(p1)
>>> t1.posts.append(p2)
>>> p2.tags.append(t2)
>>> db.session.add(t1)
>>> db.session.add(t2)
>>> db.session.add(p1)
>>> db.session.add(p2)
>>> db.session.commit()
>>> for p in t1.posts:
... print p.title
...
many to many in flask-sqlalchemy
str in python
>>> for p in t2.posts:
... print p.title
...
many to many in flask-sqlalchemy
>>> for t in p1.tags:
... print t.name
...
python
>>> for t in p2.tags:
... print t.name
...
python
sqlalchemy
>>>
链表中的结点间是自身一对一的关系
一个结点的next是另一个结点,prev则是又另外一个结点
id=db.Column(db.Integer,primary_key=True)
val=db.Column(db.Integer)
next_id=db.Column(db.Integer,db.ForeignKey('node.id'))
next=db.relationship('Node',uselist=False,remote_side=[id],backref=db.backref('prev',uselist=False))
样例
>>> n1=Node(val=1)>>> n2=Node(val=2)
>>> n3=Node(val=3)
>>> n1.next=n2
>>> n3.prev=n2
>>> db.session.add(n1)
>>> db.session.add(n2)
>>> db.session.add(n3)
>>> db.session.commit()
>>> n1.next.val
2
>>> n2.prev.val
1
>>> n2.next.val
3
>>> n3.prev.val
2
>>>
自身一对多
父亲与孩子的关系是自身一对多的关系
一个父亲可以有多个孩子
但一个孩子只会有一个父亲
id=db.Column(db.Integer,primary_key=True)
name=db.Column(db.String(40))
father_id=db.Column(db.Integer,db.ForeignKey('people.id'))
father=db.relationship('People',uselist=False,remote_side=[id],backref='sons')
样例
>>> pf=People(name='jh')>>> p1=People(name='j1')
>>> p2=People(name='j2')
>>> pf.sons.append(p1)
>>> p2.father=pf
>>> db.session.add(p1)
>>> db.session.add(p2)
>>> db.session.add(pf)
>>> db.session.commit()
>>> for p in pf.sons:
... print p.name
...
j1
j2
>>> p1.father.name
u'jh'
>>> p2.father.name
u'jh'
>>>
自身多对多
微博中用户关注和被关注是自身多对多的关系
每个用户可以关注多个用户,而他也能被多个用户关注
#中介
user_user=db.Table('user_user',db.Column('user1_id',db.Integer,db.ForeignKey('user.id'),primary_key=True),
db.Column('user2_id',db.Integer,db.ForeignKey('user.id'),primary_key=True))
id=db.Column(db.Integer,primary_key=True)
nickname=db.Column(db.String(80),unique=True)
password=db.Column(db.String(120))
concern=db.relationship('User',secondary=user_user,primaryjoin=id==user_user.c.user1_id,
secondaryjoin=id==user_user.c.user2_id,backref='concerned')
def __repr__(self):
return '<'+self.nickname+'>'#这里方便下面的查看
>>> u1=User(nickname='j1',password='123456')
>>> u2=User(nickname='j2',password='123456')
>>> u3=User(nickname='j3',password='123456')
>>> u4=User(nickname='j4',password='123456')
>>> db.session.add(u1)
>>> db.session.add(u2)
>>> db.session.add(u3)
>>> db.session.add(u4)
>>> u1.concern.append(u2)
>>> u2.concern.append(u3)
>>> u2.concern.append(u4)
>>> u3.concern.append(u2)
>>> u4.concern.append(u1)
>>> db.session.commit()
>>> u1.concern
[<j2>]
>>> u1.concerned
[<j4>]
>>> u2.concern
[<j3>, <j4>]
>>> u2.concerned
[<j1>, <j3>]
>>> u3.concern
[<j2>]
>>> u3.concerned
[<j2>]
>>> u4.concern
[<j1>]
>>> u4.concerned
[<j2>]
>>>