Reputation: 19
I am trying to make a registration page, for my website. The data is coming from the javascript frontend to the backend successfully (evident by browser logs.) and by print statements, but the incoming data is failing to commit to the database.
Background, App is made with "Role Based Access" in mind with models User, Roles and UserRoles (association table)
Influencer and Sponsor inherit from User and their primary keys and foreign keys are same. i.e (influencer_id and sponsor_id) respectively.
Here creation of instance of User first is necessary so that its (user_id) could be used to populate the primary keys of Influencer and Sponsor.
@app.route('/register', methods=['POST'])
def register():
data = request.get_json()
username = data.get('username')
email = data.get('email')
password = data.get('password')
role = data.get('role')
socialm =data.get('social_media')
handle = data.get('handle')
country = data.get('country')
followers = data.get('followerCount')
if not email or not password or role not in ['influencer', 'sponsor']:
return jsonify({"message" : "invalid inputs"}), 404
existing_user = db.session.query(User).filter(
(User.email == email) | (User.username == username)
).first()
if existing_user:
# Check specifically which field is causing the conflict
if existing_user.email == email:
return jsonify({'message': 'Email already registered'}), 400
elif existing_user.username == username:
return jsonify({'message': 'Username already taken'}), 400
new_user = User(
email=email,
password=hash_password(password),
roles=[datastore.find_or_create_role(name=role)],
active=True,
type=role,
username=username
)
try:
db.session.add(new_user)
db.session.flush()
#user_id = newuser.user_id
if (role == 'influencer'):
fname = data.get("fname")
lname = data.get("lname")
age = data.get("age")
gender = data.get("gender")
newinf = Influencer(
influencer_id = new_user.user_id,
inf_firstName=fname,
inf_lastName=lname,
inf_age=age,
inf_gender=gender,
inf_followerCount=followers,
inf_country = country,
inf_socialMedia=socialm,
inf_handle=handle,
)
db.session.add(newinf)
else:
spname = data.get("spname")
newsp = Sponsor(
sponsor_name = spname,
sponsor_followerCount=followers,
sponsor_country = country,
sponsor_socialMedia=socialm,
sponsor_handle=handle
)
db.session.add(newsp)
db.session.commit() #Suspected failing point
return jsonify({"message" : "user created", "redirect_url": url_for('login')}), 200
except Exception as e :
db.session.rollback()
print(f"Error during registration: {e}")
return jsonify({"message" : "error creating user"}), 400
error
* Detected change in '/path/to/project/file/routes.py', reloading
* Restarting with stat
Starting Local Development
Data creation in progress..
Starting Local Development
Data creation in progress..
* Debugger is active!
* Debugger PIN: 730-880-975
Username: randominfluencer, Email: [email protected], Password: 123, Role: influencer
New User: [email protected], randominfluencer, $2b$12$KpW/yS1VPdEfwlpDxlp9a.kvdlZsk3Z826DkCXZIkIHmyCy/5VWiC
New User: [email protected], randominfluencer, $2b$12$KpW/yS1VPdEfwlpDxlp9a.kvdlZsk3Z826DkCXZIkIHmyCy/5VWiC, None
/path/to/project/file/routes.py:132: SAWarning: Flushing object <User at 0x7f8e3a77f6e0> with incompatible polymorphic identity 'influencer'; the object may not refresh and/or load correctly (this warning may be suppressed after 10 occurrences)
db.session.commit()
Error during registration: (sqlite3.IntegrityError) NOT NULL constraint failed: User.email
[SQL: INSERT INTO "User" (username, email, password, active, confirmed_at, fs_uniquifier, type) VALUES (?, ?, ?, ?, ?, ?, ?)]
[parameters: (None, None, None, 1, '2024-11-24 14:34:23.744976', 'f917a93a-c42e-4ba5-8650-ba5be03f5835', 'influencer')]
(Background on this error at: https://sqlalche.me/e/20/gkpj)
127.0.0.1 - - [24/Nov/2024 14:34:28] "POST /register HTTP/1.1" 400 -
Upvotes: 0
Views: 25
Reputation: 807
It seems like when saving Influencer it is trying to create a new record - and if Influencer is derived from User - then you are missing email, username, etc.
I think what would work is after committing the User record - re-read it back as the appropriate type (Influencer/Sponsor) - then fill in additional params.
I am not sure why you can’t just create an Influencer/Sponsor record in full at registration time rather than the 2-step process.. I must be missing something.
Upvotes: 0