我对 Flask 并不陌生,但我第一次决定使用
flask-sqlalchemy
,而不是只为每个项目编写自己的 Orm。现在我遇到了一个问题,但我就是不知道如何解决它。
Traceback (most recent call last):
File "C:\Users\Flinn\OneDrive\Dokumente\MusicStore\VENV3.11.1\Lib\site-packages\flask\app.py", line 2190, in wsgi_app
response = self.full_dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Flinn\OneDrive\Dokumente\MusicStore\VENV3.11.1\Lib\site-packages\flask\app.py", line 1486, in full_dispatch_request
rv = self.handle_user_exception(e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Flinn\OneDrive\Dokumente\MusicStore\VENV3.11.1\Lib\site-packages\flask\app.py", line 1484, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Flinn\OneDrive\Dokumente\MusicStore\VENV3.11.1\Lib\site-packages\flask\app.py", line 1469, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Flinn\OneDrive\Dokumente\MusicStore\app.py", line 31, in register
user = User(
^^^^^
File "<string>", line 4, in __init__
File "C:\Users\Flinn\OneDrive\Dokumente\MusicStore\VENV3.11.1\Lib\site-packages\sqlalchemy\orm\state.py", line 561, in _initialize_instance
manager.dispatch.init(self, args, kwargs)
File "C:\Users\Flinn\OneDrive\Dokumente\MusicStore\VENV3.11.1\Lib\site-packages\sqlalchemy\event\attr.py", line 487, in __call__
fn(*args, **kw)
File "C:\Users\Flinn\OneDrive\Dokumente\MusicStore\VENV3.11.1\Lib\site-packages\sqlalchemy\orm\mapper.py", line 4391, in _event_on_init
instrumenting_mapper._check_configure()
File "C:\Users\Flinn\OneDrive\Dokumente\MusicStore\VENV3.11.1\Lib\site-packages\sqlalchemy\orm\mapper.py", line 2386, in _check_configure
_configure_registries({self.registry}, cascade=True)
File "C:\Users\Flinn\OneDrive\Dokumente\MusicStore\VENV3.11.1\Lib\site-packages\sqlalchemy\orm\mapper.py", line 4199, in _configure_registries
_do_configure_registries(registries, cascade)
File "C:\Users\Flinn\OneDrive\Dokumente\MusicStore\VENV3.11.1\Lib\site-packages\sqlalchemy\orm\mapper.py", line 4240, in _do_configure_registries
mapper._post_configure_properties()
File "C:\Users\Flinn\OneDrive\Dokumente\MusicStore\VENV3.11.1\Lib\site-packages\sqlalchemy\orm\mapper.py", line 2403, in _post_configure_properties
prop.init()
File "C:\Users\Flinn\OneDrive\Dokumente\MusicStore\VENV3.11.1\Lib\site-packages\sqlalchemy\orm\interfaces.py", line 579, in init
self.do_init()
File "C:\Users\Flinn\OneDrive\Dokumente\MusicStore\VENV3.11.1\Lib\site-packages\sqlalchemy\orm\relationships.py", line 1639, in do_init
self._generate_backref()
File "C:\Users\Flinn\OneDrive\Dokumente\MusicStore\VENV3.11.1\Lib\site-packages\sqlalchemy\orm\relationships.py", line 2128, in _generate_backref
self._add_reverse_property(self.back_populates)
File "C:\Users\Flinn\OneDrive\Dokumente\MusicStore\VENV3.11.1\Lib\site-packages\sqlalchemy\orm\relationships.py", line 1595, in _add_reverse_property
raise sa_exc.ArgumentError(
sqlalchemy.exc.ArgumentError: reverse_property 'orchestra_memberships' on relationship OrchestraMembership.user references relationship User.orchestra_memberships, which does not reference mapper Mapper[OrchestraMembership(orchestra_memberships)]
我知道这是一条很长的错误消息,可能所有这些都不是很重要,但为了澄清起见,我还将在这里发布 Flask 应用程序中的其余代码:
app.py:
import flask
from models import db # Import the SQLAlchemy db object
from models import User, Orchestra, OrchestraMembership
from flask_bcrypt import Bcrypt
app = flask.Flask(__name__)
app.config[
"SQLALCHEMY_DATABASE_URI"
] = r"sqlite:///C:\Users\Flinn\OneDrive\Dokumente\MusicStore\database.db"
db.init_app(app)
bcrypt = Bcrypt(app)
@app.route("/")
def index():
return flask.render_template("index.html")
@app.route("/register", methods=["GET", "POST"])
def register():
if flask.request.method == "POST":
full_name = flask.request.form["full_name"]
username = flask.request.form["username"]
email = flask.request.form["email"]
password = flask.request.form["password"]
hashed_password = bcrypt.generate_password_hash(password).decode("utf-8")
# Create a new user
user = User(
full_name=full_name,
username=username,
email=email,
password_hash=hashed_password,
)
db.session.add(user)
db.session.commit()
flask.flash("Registration successful. You can now log in.", "success")
return flask.redirect(url_for("login"))
@app.route("/login", methods=["GET", "POST"])
def login():
if flask.request.method == "POST":
email = flask.request.form["email"]
password = flask.request.form["password"]
user = User.query.filter_by(email=email).first()
if user and bcrypt.check_password_hash(user.password_hash, password):
# Log in the user
flask.flash("Login successful.", "success")
return flask.redirect(url_for("profile"))
else:
flask.flash("Login failed. Please check your email and password.", "error")
return flask.render_template("login.html")
@app.route("/profile")
def profile():
# Implement your profile view here
return "User Profile"
if __name__ == "__main__":
app.run()
models.py:
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from datetime import datetime
db = SQLAlchemy()
user_orchestra_association = db.Table(
"user_orchestra_association",
db.Column("user_id", db.Integer, db.ForeignKey("users.id")),
db.Column("orchestra_id", db.Integer, db.ForeignKey("orchestra_memberships.id")),
)
class OrchestraMembership(db.Model):
__tablename__ = "orchestra_memberships"
id = db.Column(Integer, primary_key=True)
user_id = db.Column(Integer, ForeignKey("users.id"))
orchestra_id = db.Column(Integer, ForeignKey("orchestra_memberships.id"))
"""
role = db.Column(String)
instruments_played = db.Column(String) # Comma-separated list or JSON array.
"""
user = relationship("User", back_populates="orchestra_memberships")
orchestra = relationship("Orchestra", back_populates="orchestra_memberships")
class User(db.Model):
__tablename__ = "users"
id = db.Column(Integer, primary_key=True)
"""
full_name = db.Column(String)
username = db.Column(String)
email = db.Column(String, unique=True)
password_hash = db.Column(String)
profile_picture = db.Column(String) # URL or File Path
"""
# short_description = db.Column(String)
# ... add other columns as needed.
# Define a one-to-many relationship with VerificationToken
verification_tokens = relationship("VerificationToken", back_populates="user")
orchestra_memberships = relationship(
"Orchestra", secondary=user_orchestra_association, back_populates="members"
)
class Orchestra(db.Model):
__tablename__ = "orchestras"
id = db.Column(Integer, primary_key=True)
## name = db.Column(String)
# ... add other columns as needed.
members = relationship(
"User",
secondary=user_orchestra_association,
back_populates="orchestra_memberships",
)
class VerificationToken(db.Model):
__tablename__ = "verification_tokens"
id = db.Column(Integer, primary_key=True)
user_id = db.Column(Integer, ForeignKey("users.id"))
token = db.Column(String, unique=True)
expiry_timestamp = db.Column(db.DateTime, default=datetime.utcnow)
# Define a many-to-one relationship with User
user = relationship("User", back_populates="verification_tokens")
class PasswordResetToken(db.Model):
__tablename__ = "password_reset_tokens"
id = db.Column(Integer, primary_key=True)
user_id = db.Column(Integer, ForeignKey("users.id"))
token = db.Column(String, unique=True)
expiry_timestamp = db.Column(db.DateTime, default=datetime.utcnow)
# Define a many-to-one relationship with User
user = relationship("User", back_populates="password_reset_tokens")
然后,当我运行测试脚本来注册新帐户时,会发生错误。
register_new_account_test.py:
import requests
import random
import string
# Define the base URL of your Flask application
base_url = "http://localhost:5000" # Change this to your application's URL
# Generate a random username, email, and password
def generate_random_string(length):
characters = string.ascii_letters + string.digits
return "".join(random.choice(characters) for _ in range(length))
random_username = generate_random_string(8)
random_email = generate_random_string(8) + "@example.com"
random_password = generate_random_string(12)
# Create a random user
user_data = {
"full_name": "Random User",
"username": random_username,
"email": random_email,
"password": random_password,
}
registration_url = base_url + "/register" # Replace with your registration endpoint URL
# Send a POST request to register the user
response = requests.post(registration_url, data=user_data)
if response.status_code == 200:
print("User registration successful.")
print(f"Username: {random_username}")
print(f"Email: {random_email}")
print(f"Password: {random_password}")
else:
print("User registration failed.")
print("Response status code:", response.status_code)
print("Response content:", response.text)
如果有人可以向我解释错误消息,并提供一些有关如何修复它的信息,我将非常感激。我已经阅读了一些文档,但我还没有真正理解所有内容。如果您有任何疑问请询问。
我尝试使用 FLASK-SQLALCHEMY 创建数据库 orm,但我只是收到错误而不是工作数据库
简单的答案是,你们的关系不匹配:
OrchestraMembership.user
指向User.orchestra_memberships
,但User.orchestra_memberships
指向Orchestra
模型。
退一步看,您的数据模型似乎不太正确。
orchestra_user_association
和OrchestraMembership
似乎扮演着类似的角色?也许您需要删除其中之一,例如删除 OrchestraMembership
并让 orchestra_user_association.orchestra_id
指向 orchestra.id
?