在 python 烧瓶中处理关系
Work with relationships in python flask
我完全是初级编程python,我想看看有没有人能指导我解决我遇到的这个问题。
我正在尝试为一家商店制作 REST API,但我被人际关系所困。我遇到的问题是我有以下端点、模型、服务,每次我尝试对 API 进行 post 时,我都会收到这些错误
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
我的观点
#!/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
)
从客户端请求中获取的 specification
类型是 str
。当调用 add_product
函数时,将创建一个 Product
对象 specification
in str
类型。
但是根据你的Product
模型,specification
是外键,应该是Specification
的对象。
解决方案:
修复add_product
函数,tableSpecification
和Product
是多对多的关系。 SQL 数据库创建第三个 table 来实现多对多关系,就像您的 product_specification
一样。
所以创建或获取一个Specification
对象,创建一个Product
对象,最后添加关系。举个例子,仅供参考:
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()
调整模型,将外键字段改为字符串字段。会和项目逻辑冲突,基本不能解决问题
我完全是初级编程python,我想看看有没有人能指导我解决我遇到的这个问题。
我正在尝试为一家商店制作 REST API,但我被人际关系所困。我遇到的问题是我有以下端点、模型、服务,每次我尝试对 API 进行 post 时,我都会收到这些错误
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
我的观点
#!/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
)
从客户端请求中获取的 specification
类型是 str
。当调用 add_product
函数时,将创建一个 Product
对象 specification
in str
类型。
但是根据你的Product
模型,specification
是外键,应该是Specification
的对象。
解决方案:
修复
add_product
函数,tableSpecification
和Product
是多对多的关系。 SQL 数据库创建第三个 table 来实现多对多关系,就像您的product_specification
一样。所以创建或获取一个
Specification
对象,创建一个Product
对象,最后添加关系。举个例子,仅供参考: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()
调整模型,将外键字段改为字符串字段。会和项目逻辑冲突,基本不能解决问题