sqlalchemy一对多的关系

Posted python成长中

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sqlalchemy一对多的关系相关的知识,希望对你有一定的参考价值。

#encoding: utf-8

from sqlalchemy import create_engine,Column,Integer,String,Float,func,and_,or_,Text,    ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker,relationship
from random import randint

HOSTNAME = 127.0.0.1

PORT = 3306

DATABASE = first_sqlalchemy

USERNAME = root

PASSWORD = 123456

#dialect+driver://username:[email protected]:port/database
DB_URI = "mysql+pymysql://{username}:{password}@{host}:{port}/"          "{db}?charset=utf8".format(username=USERNAME,password=PASSWORD,host=HOSTNAME,port=PORT,db=DATABASE)

engine = create_engine(DB_URI)

Base = declarative_base(engine)

# Session = sessionmaker(engine)
# session = Session()

session = sessionmaker(engine)() #Session(**local_kw)

#父表/从表
#user/article


class User(Base):
    __tablename__ = user
    id = Column(Integer,primary_key=True,autoincrement=True)
    username = Column(String(32),nullable=False)

    # articles = relationship("Article") #获取用户发布所有文章


class Article(Base):
    __tablename__ = article
    id = Column(Integer,primary_key=True,autoincrement=True)
    title = Column(String(50),nullable=False)
    content = Column(Text,nullable=False)
    uid = Column(Integer,ForeignKey(user.id,ondelete=RESTRICT))
    author = relationship(User,backref=articles) #sqlalchemy orm提供的

# Base.metadata.drop_all()
#
# Base.metadata.create_all()
#
#
# #添加数据
# user = User(username = ‘xiaowu‘)
# session.add(user)
# session.commit()
#
# article = Article(title = ‘圣墟‘,content = ‘吹牛逼死坑的小说,天天吹水逼‘,uid = 1)
# session.add(article)
# session.commit()

#现在有个需求,我要查询article表中关联user表的数据,同过uid查询
‘‘‘
article = session.query(Article).first()
uid = article.uid
user = session.query(User).get(uid) #get根据主键会对一个对象或None
print(user)
‘‘‘
#上面写法也行,但是有没有更简便的呢?
# from sqlalchemy.orm import relationship
#sqlalchemy为我们提供了 relationship

article = session.query(Article).first()

#获取user对象
user = article.author
print(user)
#通过author这个字段就能直接查询出User所有关联的内容
author_name = user.username
print(author_name)

#我现在又另一个需求,获取用户发布的文章,该怎么做,
#首先我们要明白用户跟文章的关系,是 一对 多关系

user = session.query(User).first()

article= user.articles
print(article)#获取文章对象 ,[<__main__.Article object at 0x0000021D7BA2FC18>]是列表

#获取用户发布的文件title

article_title = article[0].title
print(article_title)

#这时候就有疑问呢,同样是用relationship,为什么获取对象的类型却不一样,
‘‘‘
User (主表)对 Aritcle(子表) relationship 获取 aritcle的对象是列表包裹着的
而 Aritcle(子表) 对 User(主表)relationship 获取 user 的对象 就是 内存对象
要理解这种做法,就要理解一对多关系,user(用户)可以发表多篇文章,而 article(文章)
只能有一个用户发布,所以获取article的对象是列表包裹着的 
‘‘‘

#现在有一个需求 能不能 简化 relationship ,在子表显示
#author = relationship(‘User‘,backref=‘articles‘)
‘‘‘
backref 就是反关联的意思,反向引用,
article 通过 author 这个关键字 正向引用 user表中的字段
user 通过 articles 反向引用 article表中的字段
‘‘‘

 

以上是关于sqlalchemy一对多的关系的主要内容,如果未能解决你的问题,请参考以下文章

SQLAlchemy ORM 一对多关系未从数据库加载所有记录

SQLAlchemy(三):外键连表关系

在 SQLAlchemy 中加入后加入

在sqlalchemy中插入具有一对多关系的新记录

了解 SQLAlchemy ForeignKey 关系查询结果

SQLAlchemy 教程 —— 基础入门篇