JSON代表和DB镜像结构中的Python烧瓶,Sqlalchemy和Marshmallow序列化问题

发布于 01-21 17:53 字数 3884 浏览 4 评论 0原文

用烧瓶编写REST API - 我使用SQLalchemy宣布了2个简单模型( Company 地址),我还在 PostgreSql << /strong>(在pgadmin上本地运行)。

这里的模型( ret JSON 包括):

import os
import json
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
app = Flask(__name__)
app.config.from_object(os.environ['APP_SETTINGS'])
db = SQLAlchemy(app)
ma = Marshmallow(app)



#MODELS
class Company(db.Model):
__tablename__ = 'company'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
description = db.Column(db.String, nullable=False)
website = db.Column(db.Text, nullable=False)
addresses = db.relationship('Address', backref='company')

def json(self):
    return {'id': self.id,'description': self.description, 'website': self.website}

def __repr__(self):
    company_object = {
        'id': self.id,
        'description': self.description,
        'website': self.website,
        'addresses': self.addresses
    }
    return json.dumps(company_object)


def get_company(_id):
    return Company.json(Company.query.filter_by(id=_id).first())



class Address(db.Model):
__tablename__ = 'address'

id = db.Column(db.Integer, primary_key=True, autoincrement=True)
street = db.Column(db.String, nullable=False)
postcode = db.Column(db.String, nullable=False)
country = db.Column(db.String, nullable=False)
company_Id = db.Column(db.Integer,db.ForeignKey('company.id'))

def json(self):
    return {'id': self.id, 'street': self.street, 'postcode':self.postcode, 'country':self.country}

def __repr__(self):
    Address_object = {
        'id': self.id,
        'street': self.street, 
        'postcode':self.postcode, 
        'country':self.country
        }
    return json.dumps(Address_object)

这是Compnay API的 Controller (通过ID的简单获取公司返回一家带有嵌套在其中的对象地址的公司)一家公司可以有一个或多个地址)注意我试图实现棉花糖模式序列化(我认为我在那里做了一些东西 - 不确定):

from models.company_model import Company,Address
import json
from marshmallow import Schema, fields
#This below import ma from database.py --> from flask_marshmallow import Marshmallow
from database import  ma
producstAPI = Blueprint('companyAPI', __name__)

class AddressSchema(ma.Schema):
    id = fields.Int(dump_only=True)
    street = fields.String()
    postcode = fields.String()
    country = fields.String()


class CompanySchema(ma.Schema):
        id = fields.Int(dump_only=True)
        title = fields.String()
        description = fields.String()
        imageURL = fields.String()
        addresses= fields.Nested(AddressSchema,many=True)

    

# GET A Compaany via id - this company ALREADY exists in the Postgresql db with id 1 in the table Company and so  the 2 addresses on the table Address
@companyAPI.route('/api/v1/companies/<int:company_id>')
def get_company_via_company_id(company_id):
    company = Company.get_company(company_id)
    company_schema = CompanySchema()
    output = company_schema.dump(company)
    return jsonify(output)

我启动烧瓶应用程序并点击此URL'http://127.0.0.0.1:5000/api/v1/companies/1'与Postman一起测试我的代码。以下是结果:

{
  "description": "My Company",
  id": 1,
  "price": 23.45,
  "addresses": [],
  "website": "A link"
}

但是我试图在下面努力达到这种格式:

{
  "id": 1,
  "description": "My Company",
  "website": "A link",
  "addresses": [
    {
      "id": 1,
      "street": "1 dark street",
      "postcode": "00001",
      "country": "UK"
    },
    {
      "id": 1,
      "street": "1 light street",
      "postcode": "00002",
      "country": "Australia"
    }
  ]
}

我对更多嵌套/复杂的模型声明没有经验 - 我已经使用了Flat JSON结构,并且以前从未遇到过这样的问题 - 或者也许是创建的事实2个表是这里的Actuall Isssue吗?我已经制作了2个表来维护2个对象之间的数据完整性,以确保每个地址都链接到一家公司 - 我觉得棉花糖可以简化事物,但它已经成为一场噩梦。我相信这可能是一个简单的序列化问题。有人可以帮忙吗?另外,如果我必须通过API在数据库中写入,我会封闭同一问题吗?

Writing a REST API with Flask - I have declared 2 simple Models (Company and Address) using SQLAlchemy and i have also created the underlying DB and Tables in PostgreSQL (running Locally on PGAdmin).

Here the Models with (repr andjson methods included):

import os
import json
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
app = Flask(__name__)
app.config.from_object(os.environ['APP_SETTINGS'])
db = SQLAlchemy(app)
ma = Marshmallow(app)



#MODELS
class Company(db.Model):
__tablename__ = 'company'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
description = db.Column(db.String, nullable=False)
website = db.Column(db.Text, nullable=False)
addresses = db.relationship('Address', backref='company')

def json(self):
    return {'id': self.id,'description': self.description, 'website': self.website}

def __repr__(self):
    company_object = {
        'id': self.id,
        'description': self.description,
        'website': self.website,
        'addresses': self.addresses
    }
    return json.dumps(company_object)


def get_company(_id):
    return Company.json(Company.query.filter_by(id=_id).first())



class Address(db.Model):
__tablename__ = 'address'

id = db.Column(db.Integer, primary_key=True, autoincrement=True)
street = db.Column(db.String, nullable=False)
postcode = db.Column(db.String, nullable=False)
country = db.Column(db.String, nullable=False)
company_Id = db.Column(db.Integer,db.ForeignKey('company.id'))

def json(self):
    return {'id': self.id, 'street': self.street, 'postcode':self.postcode, 'country':self.country}

def __repr__(self):
    Address_object = {
        'id': self.id,
        'street': self.street, 
        'postcode':self.postcode, 
        'country':self.country
        }
    return json.dumps(Address_object)

Here is the Controller for the Compnay API ( a simple get company via id that should return a company with an array of object addresses nested inside ) a company can have one or more addresses) notice i have tried to implement the marshmallow schema Serialization ( i think i did something worng there- not really sure):

from models.company_model import Company,Address
import json
from marshmallow import Schema, fields
#This below import ma from database.py --> from flask_marshmallow import Marshmallow
from database import  ma
producstAPI = Blueprint('companyAPI', __name__)

class AddressSchema(ma.Schema):
    id = fields.Int(dump_only=True)
    street = fields.String()
    postcode = fields.String()
    country = fields.String()


class CompanySchema(ma.Schema):
        id = fields.Int(dump_only=True)
        title = fields.String()
        description = fields.String()
        imageURL = fields.String()
        addresses= fields.Nested(AddressSchema,many=True)

    

# GET A Compaany via id - this company ALREADY exists in the Postgresql db with id 1 in the table Company and so  the 2 addresses on the table Address
@companyAPI.route('/api/v1/companies/<int:company_id>')
def get_company_via_company_id(company_id):
    company = Company.get_company(company_id)
    company_schema = CompanySchema()
    output = company_schema.dump(company)
    return jsonify(output)

I start my Flask app and hit this URL 'http://127.0.0.1:5000/api/v1/companies/1' with POSTMAN to test my code. here Below is the result:

{
  "description": "My Company",
  id": 1,
  "price": 23.45,
  "addresses": [],
  "website": "A link"
}

But I am trying to acheive this format Below:

{
  "id": 1,
  "description": "My Company",
  "website": "A link",
  "addresses": [
    {
      "id": 1,
      "street": "1 dark street",
      "postcode": "00001",
      "country": "UK"
    },
    {
      "id": 1,
      "street": "1 light street",
      "postcode": "00002",
      "country": "Australia"
    }
  ]
}

I have some inexperience with more nested/complicated models declarations - i have worked with flat json structures and i never had issues like this before - or maybe the fact that creating 2 tables is the actuall isssue here? i have made 2 tables to maintain data integrity between the 2 object making sure every address is linked to a company - i tought that marshmallow would simplify things but it's becoming a bit of a nightmare. i believe this could be a simple Serialization issue. can someone help? also if i had to write in the DB via the api would i encoutner same issue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

淡淡の花香2025-01-28 17:53:14

这可能是问题中的错别字,但是该字段应命名为地址,不是吗?

class CompanySchema(ma.Schema):
        id = fields.Int(dump_only=True)
        title = fields.String()
        description = fields.String()
        price = fields.Float()
        imageURL = fields.String()
        # Here:
        # sizeOptions = fields.Nested(AddressSchema,many=True)
        addresse = fields.Nested(AddressSchema,many=True)

可能还有其他问题,因为我看不到Price来自哪里。

It could be a typo in the question, but the fields should be named addresses, shouldn't it?

class CompanySchema(ma.Schema):
        id = fields.Int(dump_only=True)
        title = fields.String()
        description = fields.String()
        price = fields.Float()
        imageURL = fields.String()
        # Here:
        # sizeOptions = fields.Nested(AddressSchema,many=True)
        addresse = fields.Nested(AddressSchema,many=True)

There may be other issues because I don't see where price comes from.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文