flask-sqlalchemy不同的关系的实例

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'

>>>


一对多

博客用户和博文是一对多的关系

一个用户有多篇博文,而一篇博文只能有一个作者


class User(db.Model):
        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处


class User(db.Model):
        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写在哪里都没所谓


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)

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则是又另外一个结点


class Node(db.Model):
        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

>>>


自身一对多

父亲与孩子的关系是自身一对多的关系

一个父亲可以有多个孩子

但一个孩子只会有一个父亲


class People(db.Model):
        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))


class User(db.Model):
        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>]
>>>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值