2017-01-16 31 views
1

我想创建蟒蛇SQLAlchemy的,这是2个表,SQLAlchemy中加入2在我的数据库表

table name : student 

- id (integer) 

- student_name (varchar(20)) 

- edu_level_id (integer) 

包含记录

id | student_name | edu_level_id 

1 | John | 2 

2 | George | 1 

表:master_edu_level

* id (integer) 
* name_level (varchar(50)) 

记录:

id | name_level | 

1 | high school 

2 | Bachelor 

3 | Master 

如何显示像记录:

id | student_name | education 


1 | John  | Bachelor 

2 | George | high school 

如果我解释这样的SQL:

select student.id, student.name,master_edu_level.name AS educatio FROM student 
left join master_edu_Level ON master_edu_level.id = student.edu_level_id 

我已经写代码:

from app import db 
from app import session 
from sqlalchemy import Table, DateTime,Date, Text, text, Column, Integer, String, MetaData, ForeignKey, select, func 
from sqlalchemy.ext.declarative import declarative_base 
from marshmallow_jsonapi import Schema, fields 
from marshmallow import validate 
from marshmallow import ValidationError 
from sqlalchemy.exc import SQLAlchemyError 
from sqlalchemy.orm import relationship 

class Student(db.Model): 
     __tablename__ = 'student' 

     id = db.Column(Integer, primary_key=True, index=True) 
     student_name = db.Column(String(20), nullable=False, index=True) 
     edu_level_id = db.Column(Integer) 

class StudentSchema(Schema): 
    not_blank = validate.Length(min=1, error='Field cannot be blank') 
    id = fields.Integer(dump_only=True) 
    student_name  = fields.String() 
    edu_level_id  = fields.String() 

    class Meta: 
     type_ = 'student' 

student_schema = StudentSchema() 


class MasterEduLevel(db.Model): 
    __tablename__ = 'master_edu_level' 
    __table_args__ = {'extend_existing': True} 

    id = db.Column(Integer, primary_key=True, index=True) 
    name_level = db.Column(String(20), nullable=False, index=True) 


class MasterEdulevelSchema(Schema): 
    not_blank = validate.Length(min=1, error='Field cannot be blank') 
    id = fields.Integer(dump_only=True) 
    name_level  = fields.String() 

    class Meta: 
     type_ = 'master_edu_level' 

schema = MasterEdulevelSchema() 

如何创建连接表的ORM在python SQLAlchemy?

感谢

+0

你的确可以(http://docs.sqlalchemy.org/en/latest/orm/nonstandard_mappings.html#mapping-a-class [上加入的顶部创建映射] -against-multiple-tables),但是你是否真的想要在[Student]中添加一个[relationship](http://docs.sqlalchemy.org/en/latest/orm/relationships.html),以便你可以例如像'student.edu_level.name_level'那样访问它,或者像查询(Student.student_name,MasterEduLevel.name_level).join(MasterEduLevel)...'这样的查询。 –

+0

@ helo1987你是否试过我的代码?我有回答你的问题吗? – theodor

回答

0

在第一步的变化模式这样的方式:

import marshmallow as mm 
from marshmallow_sqlalchemy import ModelSchema 

class StudentSchema(ModelSchema): 
    id = mm.fields.Integer(dump_only=True) 
    student_name = mm.fields.String() 
    education = mm.fields.Nested('MasterEdulevelSchema') 

    class Meta: 
     type_ = 'student' 

    @mm.post_dump 
    def format_dump(self, data): 
     education = data.pop('education') 
     data['education'] = education['name_level'] 
     return data 


class MasterEdulevelSchema(ModelSchema): 
    name_level = mm.fields.String() 

    class Meta: 
     type_ = 'master_edu_level' 

它将格式化数据的正确途径。

在下一步转储数据库实体:

student_schema = StudentSchema() 
student = db.session.query(Student).join(MasterEduLevel, Student.edu_level_id == MasterEduLevel.id).first() 
student_result = student_schema.dump(student) 

这应该工作,但我没有测试它。

顺便说一句,有很多方法可以解决这个问题。与SQLAlchemy一样,在Marshmallow一侧。

+0

喜索里iogane,我迟到了您的回复 我按照您的指示,但得到错误 '@marshmallow.post_dump NameError:名字“棉花糖”不是defined' – helo1987

+0

@ helo1987你必须在顶部导入棉花糖你的文件'进口marshmallow' ... – theodor

+0

yes..i已经放到了首位 从sqlalchemy.ext.declarative进口进口从marshmallow_jsonapi输入模式declarative_base ,场 从棉花糖进口来自SQLAlchemy的从棉花糖进口ValidationError 验证 。从sqlalchemy.orm中导入SQLAlchemyError import relationship' 与上面的例子 – helo1987

0

所以,我决定用文字查询SQLAlchemy的 这样

params = {"id":1} 
s = text("SELECT student.*, master_edu_level.name_level FROM student left join master_edu_level ON master_edu_level.id = student.edu_level_id WHERE student.id= :id") 
users_query= session.execute(s, params).fetchall() 
results = schema.dump(users_query, many=True).data 

,然后架构的学生,加个领域name_level

这样

class StudentSchema(Schema): 
    not_blank = validate.Length(min=1, error='Field cannot be blank') 
    id = fields.Integer(dump_only=True) 
    student_name  = fields.String() 
    edu_level_id  = fields.String() 
    name_level = fields.String() 

谢谢。

0

试试这个:

from app import db 
from app import session 
from sqlalchemy import Table, DateTime,Date, Text, text, Column, Integer, String, MetaData, ForeignKey, select, func 
from sqlalchemy.ext.declarative import declarative_base 
from marshmallow_jsonapi import Schema, fields 
from marshmallow import validate 
from marshmallow import ValidationError 
from sqlalchemy.exc import SQLAlchemyError 
from sqlalchemy.orm import relationship 


class MasterEduLevel(db.Model): 
    __tablename__ = 'master_edu_level' 
    __table_args__ = {'extend_existing': True} 

    id = db.Column(Integer, primary_key=True, index=True) 
    name_level = db.Column(String(20), nullable=False, index=True) 


class MasterEdulevelSchema(Schema): 
    not_blank = validate.Length(min=1, error='Field cannot be blank') 
    id = fields.Integer(dump_only=True) 
    name_level  = fields.String() 

    class Meta: 
     type_ = 'master_edu_level' 

class Student(db.Model): 
    __tablename__ = 'student' 

    id = db.Column(Integer, primary_key=True, index=True) 
    student_name = db.Column(String(20), nullable=False, index=True) 
    edu_level_id = db.Column(Integer, db.ForeignKey(MasterEduLevel.id)) 
    edu_level = db.relationship("MasterEduLevel") 

class StudentSchema(Schema): 
    not_blank = validate.Length(min=1, error='Field cannot be blank') 
    id = fields.Integer(dump_only=True) 
    student_name  = fields.String() 
    edu_level_id  = fields.String() 

    edu_level   = fields.Function(lambda x: x.edu_level) 

    # You can use Nested for get the entire object of the MaterEduLevel (comment above edu_level) 
    #edu_level   = fields.Nested("MasterEdulevelSchema") 

    # You can also specify a field of the Nested object using the 'only' attribute (comment above edu_level) 
    #edu_level   = fields.Nested("MasterEdulevelSchema", only=('name_level',)) 

    class Meta: 
     type_ = 'student' 

student_schema = StudentSchema() 
# You can also use the ONLY attribute here 
#student_schema = StudentSchema(only=('student_name', 'edu_level')) 

# Many results 
users_query = session.query(Student).all() 
results = student_schema.dump(users_query, many=True).data 

# Many results with filter 
users_query = session.query(Student).filter(Student.name.like('jo%')).all() 
results = student_schema.dump(users_query, many=True).data 

# Many results with filter in child property 
users_query = session.query(Student).join(Student.edu_level).filter(MasterEduLevel.name == 'Bachelor').all() 
results = student_schema.dump(users_query, many=True).data 

# Just one row by PK 
user = session.query(Student).get(1) #Student.id == 1 
result = student_schema.dump(user).data 
+0

嗨Jair Perrut,感谢评论,我将学习您的代码。 – helo1987

+0

Hi @ helo1987这是在文档中描述的,[SQLALchemy Relationship](https:// docs .sqlalchemy.org/en/rel_1_1/orm/basic_relationships.html)和[Marshmallow](https://marshmallow.readthedocs.io/en/latest/) –

相关问题