2017-04-12 16 views
0

저는 파이썬으로 완전히 주니어 프로그래밍입니다. 나는 만난이 문제로 누군가 나를 안내 할 수 있는지보고 싶습니다.파이썬 플라스크에서 관계를 사용하여 작업하십시오.

스토어 용 REST API를 만들려고하고 있으며 관계가 있습니다. 내가 가진 문제는 다음과 같은 엔드 포인트, 모델, 서비스를 가지고 때마다 내가 API에 게시물을 만들기 위해 노력하고 있다는 것입니다 내가 얻을 이러한 오류

AttributeError: "n" is not a valid field for <Specification(id='1', name='Polyester', date_added='2017-04-11 12:39:31.871208')>. 
WARNING:root:(sqlite3.IntegrityError) UNIQUE constraint failed: specification.name [SQL: 'INSERT INTO specification (name, date_added) VALUES (?, ?)'] [parameters: ('Polyester', '2017-04-11 12:39:31.871208')] 

내 제품 모델 :

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

specification = db.Table('product_specification', db.metadata, 
         db.Column('specification_id', db.Integer, 
            db.ForeignKey('specification.id')), 
         db.Column('product_id', db.Integer, 
            db.ForeignKey('product.id')) 
         ) 


class Product(db.Model): 
    __tablename__ = 'product' 

    id = db.Column(db.Integer, primary_key=True, autoincrement=True) 
    brand = db.Column(db.String(180), nullable=False) 
    description = db.Column(db.String(500), nullable=False) 
    price = db.Column(db.Float) 
    date_added = db.Column(db.DateTime, default=datetime.utcnow()) 

    specification = db.relationship('Specification', secondary=specification, 
            lazy='joined', backref=db.backref('product', lazy='dynamic')) 

    @staticmethod 
    def as_dict(self): 
     return dict(
      brand=self.brand, 
      description=self.description, 
      price=self.price, 
      date_added=self.date_added, 
      specification=self.specification 
     ) 

    def __repr__(self): 
     return "<Products(id='%s', brand='%s', description='%s'," \ 
       "price='%s', date_created='%s'>" % (
        self.id, 
        self.brand, 
        self.description, 
        self.price, 
        self.date_added, 
        self.specification 
       ) 


class ProductSchema(Schema): 
    id = fields.Integer(dump_only=True), 
    brand = fields.String(), 
    description = fields.String(), 
    price = fields.Float(), 
    date_added = fields.DateTime() 
    specification = fields.Nested(SpecificationsSchema) 

    class Meta: 
     type_ = 'product' 
     model = Product, 
     fields = (
      'id', 'brand', 'description', 'price', 'date_added', 'specification' 
     ) 

내 사양 모델 :

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

class Specification(db.Model): 
    __tablename__ = 'specification' 

    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(150), nullable=False, unique=True, index=True) 
    date_added = db.Column(db.DateTime, default=datetime.utcnow()) 

    @staticmethod 
    def as_dict(self): 
     return dict(
      name=self.name, 
     ) 

    def __repr__(self): 
     return "<Specification(id='%s', name='%s', date_added='%s')>" % (
      self.id, 
      self.name, 
      self.date_added, 
     ) 


class SpecificationsSchema(Schema): 
    id = fields.Integer(dump_only=True) 
    name = fields.String() 
    date_added = fields.DateTime() 


    class Meta: 
     type_ = 'specification' 
     model = Specification 
     fields = ('id', 'name', 'date_added') 

내 서비스 :

#!/usr/bin/python 
# -*- coding: utf-8 -*- 


def add_product(
    brand=None, 
    description=None, 
    price=None, 
    specification=None 
): 

    try: 
     products = Product(
      brand=brand, 
      description=description, 
      price=price, 
      specification=specification 
     ) 

     # Add product object to the db session 
     db.session.add(products) 
     # commit product object to the db session 
     db.session.commit() 
     # return product object status 
     return products 

    except IntegrityError as why: 
     # Logging the error. 
     logging.warning(why) 
     # Return none if there is product unique constraint error. 
     return None 

    except Exception as why: 
     # Logging the error. 
     logging.warning(why) 
     # Return error. 
     return None 
specification

내보기

#!/usr/bin/python 
# -*- coding: utf-8 -*- 


@api.route('/create/product', methods=['POST']) 
@cross_origin(allow_header=['Content-Type']) 
def create_products(): 
    try: 
     # Get product data 
     json_dict = request.get_json() 
     brand = json_dict['brand'] 
     description = json_dict['description'] 
     price = json_dict['price'] 
     specification = json_dict['specification'] 

    except Exception as why: 
     # Logging the error. 
     logging.warning(why) 

     # Return missed parameter error. 
     return api_response(
      http_code=res.ERROR_999['http_code'], 
      message=res.ERROR_999['message'], 
      code=res.ERROR_999['code'] 
     ) 


    product = add_product(
     brand=brand, 
     description=description, 
     price=price, 
     specification=specification 
    ) 

    # Check if product is already existed. 
    if product is None: 
     return api_response(
      http_code=res.ERROR_409['http_code'], 
      message=res.ERROR_409['message'], 
      code=res.ERROR_409['code'] 
     ) 

    # Products schema for some fields. 
    product_schema = ProductsSchemas(
     only=(
      'id', 
      'brand', 
      'price', 
      'date_added', 
      'specification' 
     )) 

    result = product_schema.dump(product).data 

    return api_response(
     http_code=res.PRODUCT_CREATED_SUCCESSFULLY['http_code'], 
     message=res.PRODUCT_CREATED_SUCCESSFULLY['message'], 
     payload=result 
    ) 

답변

1

유형은 클라이언트 요청에서 얻을은 str입니다. add_product 함수를 호출 할 때 Product 개체는 specificationstr 유형으로 생성됩니다.

Product 모델에 따르면 specification은 외래 키이며 Specification의 개체 여야합니다.

솔루션 :

  1. 수정 add_product 기능, 테이블 SpecificationProduct은 다 대다 관계이다. SQL 데이터베이스는 product_specification처럼 다 대다 관계를 성취 할 수있는 세 번째 테이블을 만듭니다.

    Specification 개체를 만들거나 가져 와서 Product 개체를 만들고 마지막으로 관계를 추가하십시오. 여기에 단지 참조 용으로 예입니다 : 당신의 모델 Ajust

    def add_product(brand=None, description=None, price=None, specification=None): 
        spec = Specification(name=specification) 
        product = Product(brand=brand, description=description, price=price, specification=spec) 
        product.specification.append(spec) 
        db.session.add_all([spec, product]) 
        db.session.commit() 
    
  2. 을, 문자열 필드에 외래 키 필드를 변경합니다. 그것은 프로젝트 논리와 충돌 할 것이고, 문제를 근본적으로 풀지는 못합니다.

+0

덕분에 그것은 나에게 많은 도움과 작동 방식을 이해 @aishenghuomeidaoli. – Fanatic