sqlalchemy多外键关联

一、前言

  如果有张表A的多个字段关联另一张表B的一个字段,就如同一个客户表的账单地址和发货地址,同时关联地址表中的id字段。

二、事例

# -*- coding: UTF-8 -*-
from sqlalchemy import create_engine
from sqlalchemy import Integer, ForeignKey, String, Column
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship

engine = create_engine("mysql+pymysql://bigberg:[email protected]:3306/study",
                       encoding="utf-8", )  # 连接数据库,echo=True =>把所有的信息都打印出来

Base = declarative_base()  # 生成orm基类

class Customer(Base):
    __tablename__ = ‘customer‘
    id = Column(Integer, primary_key=True)
    name = Column(String(32), nullable=False)
    # 多个外键关联
    billing_address_id = Column(Integer, ForeignKey("address.id"))
    shopping_address_id = Column(Integer, ForeignKey("address.id"))
    # foreign_keys 一定要加,否则会报错
    billing_address = relationship("Address",foreign_keys=[billing_address_id])
    shopping_address = relationship("Address",foreign_keys=[shopping_address_id])

class Address(Base):
    __tablename__ = ‘address‘
    id = Column(Integer, primary_key=True)
    street = Column(String(64), nullable=False)
    city = Column(String(64), nullable=False)
    state = Column(String(64), nullable=False)

    def __repr__(self):
        return "省份:%s 城市:%s 街区:%s" %(self.state, self.city, self.street)

# 创建表
Base.metadata.create_all(engine)

multi_fk

插入数据,为了整体的简洁,数据操作在另一张表进行

 1 # -*- coding: UTF-8 -*-
 2 import multi_fk
 3 from multi_fk import Customer
 4 from multi_fk import Address
 5 from sqlalchemy.orm import sessionmaker
 6
 7 # 创建session会话
 8 Session_class = sessionmaker(bind=multi_fk.engine)
 9 # 生成session实例
10 session = Session_class()
11
12 # 数据
13 address_obj1 = Address(street=‘daguanlu‘, city=‘hz‘, state=‘zj‘)
14 address_obj2 = Address(street=‘gudunlu‘, city=‘hz‘, state=‘zj‘)
15 address_obj3 = Address(street=‘xinjiekou‘, city=‘nj‘, state=‘js‘)
16 session.add_all([address_obj1,address_obj2,address_obj3])
17
18 customer_obj1 = Customer(name="bigberg", billing_address=address_obj1,
19                          shopping_address=address_obj2)
20
21 customer_obj2 = Customer(name="Jack", billing_address=address_obj3,
22                          shopping_address=address_obj3)
23
24 session.add_all([customer_obj1,customer_obj2])
25
26 session.commit()

multi_fk_data

数据和表结构

mysql> select * from address;
+----+-----------+------+-------+
| id | street    | city | state |
+----+-----------+------+-------+
|  1 | daguanlu  | hz   | zj    |
|  2 | gudunlu   | hz   | zj    |
|  3 | xinjiekou | nj   | js    |
+----+-----------+------+-------+
3 rows in set (0.00 sec)

mysql> select * from customer;
+----+---------+--------------------+---------------------+
| id | name    | billing_address_id | shopping_address_id |
+----+---------+--------------------+---------------------+
|  1 | bigberg |                  1 |                   2 |
|  2 | Jack    |                  3 |                   3 |
+----+---------+--------------------+---------------------+
2 rows in set (0.00 sec)

mysql> desc address;
+--------+-------------+------+-----+---------+----------------+
| Field  | Type        | Null | Key | Default | Extra          |
+--------+-------------+------+-----+---------+----------------+
| id     | int(11)     | NO   | PRI | NULL    | auto_increment |
| street | varchar(64) | NO   |     | NULL    |                |
| city   | varchar(64) | NO   |     | NULL    |                |
| state  | varchar(64) | NO   |     | NULL    |                |
+--------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

mysql> desc customer;
+---------------------+-------------+------+-----+---------+----------------+
| Field               | Type        | Null | Key | Default | Extra          |
+---------------------+-------------+------+-----+---------+----------------+
| id                  | int(11)     | NO   | PRI | NULL    | auto_increment |
| name                | varchar(32) | NO   |     | NULL    |                |
| billing_address_id  | int(11)     | YES  | MUL | NULL    |                |
| shopping_address_id | int(11)     | YES  | MUL | NULL    |                |
+---------------------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

查询

# -*- coding: UTF-8 -*-

import multi_fk
from multi_fk import Customer
from multi_fk import Address
from sqlalchemy.orm import sessionmaker

# 创建session会话
Session_class = sessionmaker(bind=multi_fk.engine)
# 生成session实例
session = Session_class()

obj = session.query(Customer).filter(Customer.name==‘bigberg‘).first()
print(obj.name,‘\n‘,‘bill_address:‘,obj.billing_address,‘\n‘,
      ‘shopping_address:‘, obj.shopping_address)
session.commit()

#输出
bigberg
 bill_address: 省份:zj 城市:hz 街区:daguanlu
 shopping_address: 省份:zj 城市:hz 街区:gudunlu

multi_fk_query

原文地址:https://www.cnblogs.com/bigberg/p/8330042.html

时间: 2024-10-16 12:31:03

sqlalchemy多外键关联的相关文章

sqlalchemy操作----外键关联,relationship

... #!_*_coding:utf-8_*_ #__author__:"Alex huang" import sqlalchemy from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column,Integer,String,ForeignKey from sqlalchemy.orm import r

使用sqlalchemy的ORM创建外键关联时报错

在学习使用sqlalchemy模块的时候踩了一个坑,分享一下. 埋下隐患 我先用下面的语句创建了一张学生信息表: > CREATE TABLE student ( -> id INT UNSIGNED AUTO_INCREMENT, -> name VARCHAR(20) NOT NULL, -> age TINYINT, -> PRIMARY KEY (id) -> ); 表里就3个字段:自增id(无符号的数字,自增id不会是负数,当然用无符号,感觉自己好专业),na

主键关联、外键关联的区别

主键关联.唯一外键关联 的区别 主键关联是指的一个表的主键和另外一个表的主键关联外键关联是指的一个表的主键和另外一个表的非主键关联 主键关联:    person_t:      person_id      address_id address_t      address_id      address_name 他们通过 address_id 关联是外键关联 person_t:      person_id      persion_name    address_t      perso

外键关联非主键id时-hbm.xml配置,及其分页查询DaoImpl

表关联时,外键关联非主键id时-hbm.xml配置: (由于hibernate默认为关联主键查询,故需要配置相关hql语句的属性) <many-to-one name="areas" class="com.hnqy.entity.Areas" fetch="select" property-ref="areaid" foreign-key="areaid"> <column name=&q

Entity Framework - 基于外键关联的单向一对一关系

代码的世界,原以为世界关系很简单,确道是关系无处不在.NET世界里ORM框架中EntityFramework作为其中翘楚,大大解放了搬砖工作的重复工作,着实提高了不少生产力,而也碰到过不少问题!比如关系的映射! 一对一关系的映射: 用户账户密码信息表:包含用户名 密码 邮箱等账户登录时的信息 public class SystemAccount { public SystemAccount() { Id = DateUtils.GeneratedNewGuid(); } public Guid

清除oracl中有主外键关联的表中的部分数据。

1.禁用主外键BEGINfor c in (select 'ALTER TABLE '||TABLE_NAME||' DISABLE CONSTRAINT '||constraint_name||' ' as v_sql from user_constraints where CONSTRAINT_TYPE='R') loop EXECUTE IMMEDIATE c.v_sql;end loop;end;2.清空数据源.清空所有数据.一般情况是对表进行条件删除.begin for ec in (

hibernate一对一双向外键关联

一对一双向外键关联:双方都持有对方的外键关联关系. 主控方和一对一单向外键关联的情况是一样的,主要的差异表现为,被空方需要添加: @OneToOne(mappedBy="card") //被控方 主控方必须交给其中的一方去控制,因为不可以双方都同时拥有控制对方的权利,假如是这样的话是没有办法保存成功的.这就是为什么需要指定mappenBy="card"的原因. 1.IdCard.java实体类: package oto_bfk; import javax.persi

《Entity Framework 6 Recipes》中文翻译系列 (29) ------ 第五章 加载实体和导航属性之过滤预先加载的实体集合和修改外键关联

翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-13  过滤预先加载的实体集合 问题 你想过滤预先加载的实体集合,另外,你想使用Code-First来管理数据访问 解决方案 实体框架不支持直接使用Include()时过滤关联实体集合,但我们可以通过创建一个匿名类型来完成同样的事情,匿名类型包含实体和要过滤的关联实体集合. 假设你有如图5-28所示的概念模型 图5-28 一个包含movies(电影)和它的categories(目录)的模

数据库一对一的两种关联 主键关联和外键关联

关联映射:一对一 一对一关系就如球队与球队所在地址之间的关系,一支球队仅有一个地址,而一个地址区也仅有一支球队. 数据表间一对一关系的表现有两种,一种是外键关联,一种是主键关联.图示如下: 一对一外键关联: 一对一主键关联:要求两个表的主键必须完全一致,通过两个表的主键建立关联关系 出自:http://hi.baidu.com/websatyr/item/10e3d83766ffb3f42784f481