Hallo,
ich habe ein Problem mit Sqlalchemy. Und zwar speichere ich das Userobjekt nach dem Login innerhalb von session in Flask.
Wenn ich nun aber nachträglich darauf zugreife, kommt folgende Fehlermeldung:
sqlalchemy.orm.exc.DetachedInstanceError
DetachedInstanceError: Parent instance <UserGroup at 0xb53c42cc> is not bound to a Session; lazy load operation of attribute 'rights' cannot proceed
Ich denke, das hängt doch irgendwie damit zusammen. Was kann ich tun, damit die Objekte (und auch deren Attribute) immer erreichbar bleiben?
Vielen Dank.
Logikproblem SQLAlchemy
Das hört sich irgendwie etwas seltsam an, was du da versuchst. Hast du ein kleines Codebeispiel?
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Und Du glaubst ernsthaft, dass Dir jetzt irgend jemand ohne Deinen Code, ohne lauffähiges Minimalbeispiel oder irgend eine Form von detaillierten Beschreibungen, *was* Du in Deinem Code machst, diese Frage beantowrten kann? Bei allem Respekt, aber als erfahrener User hier im Forum solltest Du doch wissen, dass Du schon ausreichend Informationen posten musst, um eine produktive Antwort zu erhalten!
Man kann hier nur die Fehlermeldung (die Du auch in Code-Tags setzen solltest!) wiederholen: Das `UserGroup`-Objekt ist nicht an eine (SQLALchemy-)Session gebunden - wieso, dass kann hier niemand ohne Code sagen
Nebenbei: Sowohl Flask als auch SQLALchemy besitzen "Session"-Objekte - auch dahingehend erscheint mir Dein Beitrag viel zu unpräzise bzw. uneindeutig.
Da Flask out of the box gar keine SQLAlchemy-Unterstützung anbietet, wissen wir ja auch nicht einmal, wie Du diese umsetzt. Baust Du Dir alles selber zusammen, oder nutzt Du ein Plugin für Flask? Wie genau gehst Du dann vor?
Man kann hier nur die Fehlermeldung (die Du auch in Code-Tags setzen solltest!) wiederholen: Das `UserGroup`-Objekt ist nicht an eine (SQLALchemy-)Session gebunden - wieso, dass kann hier niemand ohne Code sagen
Nebenbei: Sowohl Flask als auch SQLALchemy besitzen "Session"-Objekte - auch dahingehend erscheint mir Dein Beitrag viel zu unpräzise bzw. uneindeutig.
Da Flask out of the box gar keine SQLAlchemy-Unterstützung anbietet, wissen wir ja auch nicht einmal, wie Du diese umsetzt. Baust Du Dir alles selber zusammen, oder nutzt Du ein Plugin für Flask? Wie genau gehst Du dann vor?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Ohje, das tut mir leid. Zu wenig Informationen wollte ich auf keinen Fall geben, es war mir nur nicht ganz klar, wie ich das am besten rüberbringe, weil lauffähiger Code wird etwas schwierig :-/
UserGroup:
Das Datenbankbackend:
Im Programmcode verwende ich das Sessionobjekt von Flask.
dies wird folgendermaßen verwendet:
Die eigentliche Fehlermeldung entsteht hierbei bei folgendem Code:
Ich hoffe, die Codebeispiele helfen euch etwas, ihr könnt aber gerne jederzeit nachfragen. Meine größte Sorge ist, dass ich hier einen riesengroßen Logikfehler eingebaut habe :-/
UserGroup:
Code: Alles auswählen
class UserGroup(object):
link = None
id = None
name = None
def __init__(self,**kwargs):
self.link = database.query(database.UserGroup).filter_by(**kwargs).first()
if not self.link:
raise lib.exceptions.NotExistingError
self.id = self.link.id
self.name = self.link.name
@staticmethod
def search(**kwargs):
l = []
for x in database.query(database.UserGroup).filter_by(**kwargs):
l.append(UserGroup(id=x.id))
return l
@staticmethod
def create(name,**kwargs):
if UserGroup.search(name=name):
raise lib.exceptions.AlreadyExistingError
g = database.UserGroup(name=name,**kwargs)
g.create()
g2 = UserGroup(id=g.id)
return g2
@property
def rights(self):
l = []
for x in self.link.rights:
l.append(UserRight.search(id=x.id)[0])
return l
def allowed(self,right):
for x in self.rights:
if x.name == right:
return True
return False
def allow(self,right):
if type(right) == str:
right = UserRight(name=right)
if self.allowed(right.name):
return True
self.link.rights.append(right.link)
self.save()
return True
def forbid(self,right):
if type(right) == str:
right = UserRight(name=right)
if not self.allowed(right.name):
return True
for c,x in enumerate(self.link.rights):
if x.name == right.name:
del(self.link.rights[c])
self.save()
return True
def save(self):
database.do(self.link)
def __repr__(self):
return "<UserGroup %s>" % (self.name)
Code: Alles auswählen
class UserGroup(Base):
__tablename__ = "groups"
id = Column(Integer, primary_key=True)
name = Column(Text)
rights = relationship("UserRight",secondary=usergroup_userright,backref="groups")
def create(self):
do(self)
return self
def __repr__(self):
return "<Database:UserGroup (%s)" % (self.name)
dies wird folgendermaßen verwendet:
Code: Alles auswählen
@app.route("/login",methods=["POST","GET"])
def login():
if request.method != "POST":
return templates.load("login.tpl").render(session=session)
else:
username = request.form["username"]
password = request.form["password"]
if not User.check(username,password):
return "Error!"
user = User(username=username)
user.login(password)
session["user"] = user
return redirect(url_for("management"))
Code: Alles auswählen
def check_permission(session,right):
if not session["user"]:
return False
if not session["user"].allowed(right):
return False
return True
@sprudel: Ich vermute mal das sie Session-Daten in der DB gespeichert werden und die SQLAlchemy-Objekte das (de)serialisieren nicht überleben, zumindest nicht komplett. In so einer Session würde ich nichts allzu komplexes speichern. Eher die User-ID und damit dann das Objekt aus der DB holen.
Hmm, du vermutest also, dass das Problem ist, dass ich das gesamte Objekt in der Session speichere, und nicht nur eine einfache UserID?
Das klingt natürlich logisch, und das habe ich mir ehrlich gesagt so noch garnicht überlegt.
Findest du denn sonst noch irgendwelche groben Fehler in meinem Code? Ich bin bei der Programmierung zugegebenermaßen noch etwas unsicher, ob überhaupt mein Modell (mit den getrennten Objekten usw.) passt
Das klingt natürlich logisch, und das habe ich mir ehrlich gesagt so noch garnicht überlegt.
Findest du denn sonst noch irgendwelche groben Fehler in meinem Code? Ich bin bei der Programmierung zugegebenermaßen noch etwas unsicher, ob überhaupt mein Modell (mit den getrennten Objekten usw.) passt