2017-01-16 8 views
1

私はpythonの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 
0123私はこのようなSQLを説明する場合

id | student_name | education 


1 | John  | Bachelor 

2 | George | high school 

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 

私はすでにコードを書く:のようなレコードを表示する方法

テーブルのORMを結合を作成する方法
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() 

PythonのSQLAlchemy?

おかげで最初のステップ変化スキーマように

+0

-against-multiple-tables)、実際には[Student]に[relationship](http://docs.sqlalchemy.org/en/latest/orm/relationships.html)を追加することを意味しました。 'student.edu_level.name_level'のようにアクセスするか、' query(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

こんにちはsoryのiogane、私はあなたの指示に従いますが、エラー '@marshmallow.post_dump NameErrorなっ後半にお返事 午前:名「マシュマロは」あなたが一番上にマシュマロをインポートする必要がhelo1987 @ – helo1987

+0

をdefined'されていませんあなたはSQLAlchemyのからマシュマロインポートValidationErrorを から を検証マシュマロのインポートから フィールド、すでにsqlalchemy.ext.declarativeインポートからトップ の輸入を置く – theodor

+0

yes..iがmarshmallow_jsonapiインポートスキーマから をdeclarative_base ... '輸入marshmallow'を提出します。 exc import SQLAlchemyError sqlalchemy.ormのインポート関係 ' トップの例と同じです。 – helo1987

0

ので、私はこの

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 

などのテキストクエリSQLAlchemyの を使用して決定してから、スキーマの学生のために、この

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() 

はあなたに感謝のような分野にname_level

を追加します。

0

これを試してください:あなたは確かに(http://docs.sqlalchemy.org/en/latest/orm/nonstandard_mappings.html#mapping-a-class [加入の上にマッピングを作成]することができます

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

こんにちは@ helo1987これは、ドキュメント[SQLALchemy Relationship](https:// docs .sqlalchemy.org/en/rel_1_1/orm/basic_relationships.html)と[Marshmallow](https://marshmallow.readthedocs.io/ja/latest/) –

関連する問題