【发布时间】:2022-01-09 20:29:59
【问题描述】:
我有一个函数可以在表中执行插入操作。所以基本上我每次用户吃食物时都会尝试插入数据。
我试图用正文发布邮递员的数据
{
"id_menu" : 4,
"id_user" : 4
}
它工作正常,但我第二次尝试发布相同的请求时,数据不会存储到数据库中。它返回状态码 200,并带有成功消息,即使数据没有到来。但是当我尝试使用不同的菜单或用户时,效果很好。
所以问题是,我无法发布数据重复数据。只有当用户已经吃过菜单时才会出现问题。每次我通过/addHidangan功能发布吃过的菜单,它都不会被存储。我做错了什么?是关系吗?还是代码?谢谢
使用 postgresql 作为我的数据库
我是通过下面的函数来存储数据的,这个函数会请求菜单的id和用户的id,并将其存储到表menu_hidangan_user
@app.route('/hidangan', methods=['POST'])
def addHidangan():
try:
id_menu = request.json['id_menu']
id_user = request.json['id_user']
menu = Resep.query.filter_by(id=id_menu).first()
user = Users.query.filter_by(id=id_user).first()
menu.menu_user.append(user)
db.session.add(menu)
db.session.commit()
return jsonify({'statusCode': 200, 'message': 'Success'})
except Exception as e:
return jsonify({'statusCode': 400, 'err': True, 'message': str(e)})
以id为主键,menu_makanan为与表menu_hidangan_user的关系的一类Users
class Users(db.Model):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(30), unique=True, nullable=False)
nama = db.Column(db.String(30), nullable=False)
password = db.Column(db.String(100), nullable=False)
telepon = db.Column(db.String(20), nullable=False)
usia = db.Column(db.Integer, nullable=False)
status_diabetes = db.Column(db.String(30), nullable=False)
berat_badan = db.Column(db.Integer, nullable=False)
tinggi_badan = db.Column(db.Integer, nullable=False)
timestamp = db.Column(db.DateTime, nullable=False,
server_default=db.func.current_timestamp())
menu_makanan = db.relationship(
'Resep', secondary=menu_hidangan_user, backref="menu_user")
kadar_gula = db.relationship(
"KadarGulaDarahUser", backref="kadar_gula_user")
一类包含食谱细节的食谱
class Resep(db.Model):
id = db.Column(db.Integer, primary_key=True)
nama = db.Column(db.String(30), unique=True, nullable=False)
detail = db.Column(db.Text, nullable=False)
gula = db.Column(db.Integer, nullable=False)
kalori = db.Column(db.Integer, nullable=False)
protein = db.Column(db.Integer, nullable=False)
lemak = db.Column(db.Integer, nullable=False)
kategori = db.Column(db.String(25), nullable=False)
img_url = db.Column(db.Text, nullable=False)
timestamp = db.Column(db.DateTime, nullable=False,
server_default=db.func.current_timestamp())
还有一个名为menu_hidangan_user 的表。一个用户可以吃一个食物,每次用户吃一个食物,用户id和菜谱id都会存储在这个表中。
menu_hidangan_user = db.Table('menu_hidangan_user',
db.Column('id', db.Integer,
primary_key=True),
db.Column('id_resep', db.Integer, db.ForeignKey(
'resep.id'), nullable=False, unique=False),
db.Column('id_user', db.Integer, db.ForeignKey(
'users.id'), nullable=False, unique=False),
db.Column('timestamp', db.DateTime, nullable=False,
server_default=db.func.current_timestamp())
)
如果你需要复制,这里是完整的代码
from flask import Flask, json, request, jsonify, session
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from dotenv import load_dotenv
import os
import datetime
# Init
load_dotenv()
POSTGRESQL_USERNAME = os.getenv("POSTGRESQL_USERNAME")
POSTGRESQL_PASSWORD = os.getenv("POSTGRESQL_PASSWORD")
POSTGRESQL_HOST = os.getenv("POSTGRESQL_HOST")
POSTGRESQL_DB_NAME = os.getenv("POSTGRESQL_DB_NAME")
ENDPOINT = '/api'
POSTGRESQL_URI = f"postgresql://{POSTGRESQL_USERNAME}:{POSTGRESQL_PASSWORD}@{POSTGRESQL_HOST}/{POSTGRESQL_DB_NAME}"
app = Flask(__name__)
basedir = os.path.abspath(os.path.dirname(__file__))
app.secret_key = "hehe"
# Database
app.config['SQLALCHEMY_DATABASE_URI'] = POSTGRESQL_URI
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# Init DB
db = SQLAlchemy(app)
# Init ma
ma = Marshmallow(app)
# Many to Many Relationship
menu_hidangan_user = db.Table('menu_hidangan_user',
db.Column('id', db.Integer,
primary_key=True),
db.Column('id_resep', db.Integer, db.ForeignKey(
'resep.id'), nullable=False, unique=False),
db.Column('id_user', db.Integer, db.ForeignKey(
'users.id'), nullable=False, unique=False),
db.Column('timestamp', db.DateTime, nullable=False,
server_default=db.func.current_timestamp())
)
## == 1. User Class ========= ##
class Users(db.Model):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(30), unique=True, nullable=False)
nama = db.Column(db.String(30), nullable=False)
password = db.Column(db.String(100), nullable=False)
telepon = db.Column(db.String(20), nullable=False)
usia = db.Column(db.Integer, nullable=False)
status_diabetes = db.Column(db.String(30), nullable=False)
berat_badan = db.Column(db.Integer, nullable=False)
tinggi_badan = db.Column(db.Integer, nullable=False)
timestamp = db.Column(db.DateTime, nullable=False,
server_default=db.func.current_timestamp())
menu_makanan = db.relationship(
'Resep', secondary=menu_hidangan_user, backref="menu_user")
kadar_gula = db.relationship(
"KadarGulaDarahUser", backref="kadar_gula_user")
def __init__(self, email, nama, password, telepon, usia, status_diabetes, berat_badan, tinggi_badan):
self.email = email
self.nama = nama
self.password = password
self.telepon = telepon
self.usia = usia
self.status_diabetes = status_diabetes
self.berat_badan = berat_badan
self.tinggi_badan = tinggi_badan
# User Schema
class UserSchema(ma.Schema):
class Meta:
fields = ('email', 'nama', 'telepon', 'usia',
'status_diabetes', 'berat_badan', 'tinggi_badan', 'timestamp')
# Init Schema
user_schema = UserSchema()
users_schema = UserSchema(many=True)
## == End of User Class ========= ##
## == 2. Resep Class ========= ##
class Resep(db.Model):
id = db.Column(db.Integer, primary_key=True)
nama = db.Column(db.String(30), unique=True, nullable=False)
detail = db.Column(db.Text, nullable=False)
gula = db.Column(db.Integer, nullable=False)
kalori = db.Column(db.Integer, nullable=False)
protein = db.Column(db.Integer, nullable=False)
lemak = db.Column(db.Integer, nullable=False)
kategori = db.Column(db.String(25), nullable=False)
img_url = db.Column(db.Text, nullable=False)
timestamp = db.Column(db.DateTime, nullable=False,
server_default=db.func.current_timestamp())
def __init__(self, nama, detail, gula, kalori, protein, lemak, kategori, img_url):
self.nama = nama
self.detail = detail
self.gula = gula
self.kalori = kalori
self.protein = protein
self.lemak = lemak
self.kategori = kategori
self.img_url = img_url
# Resep Schema
class ResepSchema(ma.Schema):
class Meta:
fields = ('id', 'nama', 'detail', 'gula',
'kalori', 'protein', 'lemak', 'kategori', 'img_url', 'timestamp')
# Init Schema
resep_schema = ResepSchema()
reseps_schema = ResepSchema(many=True)
## == End of Resep Class ========= ##
## == 3. KadarGulaDarahUser Class ========= ##
class KadarGulaDarahUser(db.Model):
id = db.Column(db.Integer, primary_key=True)
id_user = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
kadar_gula_darah = db.Column(db.Integer, nullable=False)
timestamp = db.Column(db.DateTime, nullable=False,
server_default=db.func.current_timestamp())
def __init__(self, id_user, kadar_gula_darah):
self.id_user = id_user
self.kadar_gula_darah = kadar_gula_darah
# KadarGulaDarahUser Schema
class KadarGulaDarahUserSchema(ma.Schema):
class Meta:
fields = ('id', 'id_user', 'kadar_gula_darah', 'timestamp')
# Init Schema
kadarguladarahuser_schema = KadarGulaDarahUserSchema()
kadarguladarahusers_schema = KadarGulaDarahUserSchema(many=True)
class KonsumsiGulaUserSchema(ma.Schema):
class Meta:
fields = ('total_gula', 'tanggal')
konsumsigulausers_schema = KonsumsiGulaUserSchema(many=True)
## == End of KadarGulaDarah Class ========= ##
# FR-03. User dapat menambahkan hidangan untuk hari ini
@app.route(f'{ENDPOINT}/hidangan', methods=['POST'])
def addHidangan():
try:
id_menu = request.json['id_menu']
id_user = request.json['id_user']
menu = Resep.query.filter_by(id=id_menu).first()
user = Users.query.filter_by(id=id_user).first()
print(type(menu.menu_user))
menu.menu_user.append(user)
db.session.add(menu)
db.session.commit()
return jsonify({'statusCode': 200, 'message': 'Success'})
except Exception as e:
return jsonify({'statusCode': 400, 'err': True, 'message': str(e)})
if __name__ == "__main__":
app.run(debug=True)
【问题讨论】:
-
没有错误信息,API返回200成功但数据没有来
-
多对多关系在每对链接行的链接表上只有一条记录。创建该链接记录后,进一步尝试创建新记录只会覆盖您找到的现有记录。您可能需要考虑使用 association object 模式并增加计数器列,而不是尝试添加新行。
标签: python postgresql flask flask-sqlalchemy flask-restful