创建一对一和多对多关系的数据库表,首先引入所需方法,
并创建连接数据库的 engine 、生成映射类的 Base 和处理数据增删改查的 session :
from sqlalchemy import (create_engine, Column, Integer, String,
ForeignKey, Table)
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, backref, sessionmaker
engine = create_engine('mysql://root@localhost/test?charset=utf8')
Base = declarative_base(engine)
session = sessionmaker(engine)()
创建两个一对一的映射类,User 和 Course 。
注意,默认 Course 实例的 user 属性值为一个外键关联的 User 对象,
而 User 实例的 course 属性值为列表,列表里是一个外键关联的 Course 实例,
所以在 Course 映射类的 relationship 中,backref 里通常设置 uselist=False :
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String(64), unique=True, nullable=False)
def __repr__(self):
return '<User: {}>'.format(self.name)
class Course(Base):
__tablename__ = 'course'
id = Column(Integer, ForeignKey('user.id'), primary_key=True)
name = Column(String(64), unique=True, nullable=False)
user = relationship('User', backref=backref('course', uselist=False))
def __repr__(self):
return '<Course: {}>'.format(self.name)
接下来创建 tag 标签表,与 course 表为多对多的关系。
首先创建中间表的映射类,用 Table 这个特殊类创建,此类的实例就是映射类。
该类在实例化时,接收 4 个参数:
1、数据表名字 2、Base.metadata
3 和 4、两个 Column(列名,数据类型,外键,主键)
Rela = Table('rela', Base.metadata,
Column('tag_id', Integer, ForeignKey('tag.id'), primary_key=True),
Column('course_id', Integer, ForeignKey('course.id'), primary_key=True)
)
创建 Tag 映射类:
class Tag(Base):
__tablename__ = 'tag'
id = Column(Integer, primary_key=True)
name = Column(String(64), unique=True)
course = relationship('Course', secondary=Rela, backref='tag')
def __repr__(self):
return '<Tag: {}>'.format(self.name)
使用 Base 的 create_all 方法生成 4 张数据库表:
Base.metadata.create_all()
接下来,生成几个实例并使用 session 传入数据库:
u = User(name='Kobe')
c = Course(name='MySQL 基础', user=u)
t = Tag(name='Python')
# 使用 append 方法将 Course 实例放到 Tag 实例的 course 属性值的列表里
# 这样,这俩实例就互相关联了
t.course.append(c)
for i in (u, c, t):
session.add(i)
session.commit()
以上代码在 python shell 里也是一样的,不过需要注意:
如果这些映射类不是全部创建完一并生成数据库表的话,
比如先生成了 user 表和 course 表,
然后就创建了实例并用 session 提交到数据库,
之后又创建了中间表和 tag 表,
这时,之前的 Course 类的实例的变量就不能用了,
因为 Course 类的外键关联发生了变化
此时,需要先执行 session.close()
复位 session,
然后重新处理数据即可。
网友评论