bojanb wrote: > > If I understood correctly, you suggest adding @validates method for > the column that I don't want to be null on commit? That doesn't work > since it wouldn't allow me to store objects with null attributes in > the current transaction. > > In fact, @validates is even more restrictive than a non-null > constraint, since the latter lets the object attribute be null all the > way until flush.
the foreign key attribute. Since you're using relation(), you never touch this attribute yourself. SQLAlchemy's unit of work attempts to set it to None during the flush. If I understand correctly, you intend for these columns to be "not nullable" when the transaction commits. So yes this approach would require deferring any flush steps until the end. > > What I need is a deferred constraint, ie. a constraint that can be > violated in a flush, but never in a commit. Fine. Build yourself a SessionExtension that checks for this condition in the before_commit() method. Your @validates method can be used to gather up all the "Nones" into a collection that the extension checks (i.e. each time @validates is called, place current value in a dict keyed to the object id, inside another dict keyed to the current session id. when non-None comes in, remove the key. then the extension just says, "if mydict[id(session)]: raise Exception(...)"). >I can have that by doing a > check before each commit (since that's an operation that is performed > explicitly in the application), but ondelete='RESTRICT' is not honored > in such a setup. > > On Oct 26, 4:13 pm, "Michael Bayer" <[email protected]> wrote: >> bojanb wrote: >> >> > I have columns in my database that logically shouldn't be null. >> > However, I allow them to be null while the user is editing (creating) >> > objects interactively. As this is done in a transaction, and values >> > are checked before a commit, it's assured that nobody else ever sees >> > invalid values and the integrity of the data is preserved. >> >> > This would be an ideal use case for deferred constraints; >> > unfortunately, Postgres doesn't support deferred CHECK constraints so >> > the validation is done in code. This in turn means that the fields are >> > not declared as "nullable=False". >> >> > This leads to a problem when referential integrity needs to be >> > preserved. When a referred object is deleted, SQLA's default behavior >> > is to set child's object foreign key field to None (e.g. see >> >http://groups.google.com/group/sqlalchemy/browse_thread/thread/1f9990...). >> > This in turn lets the RDBMS delete the referred object, instead of >> > throwing referential integrity exception. I am left with hanging child >> > objects even though I specified ondelete='RESTRICT' for the relation. >> >> > Is there any way around this? I've tried passive_deletes='all' but it >> > didn't do the trick... >> >> why not just add a @validates method to your class, set for the foreign >> key attribute, which ensures that the incoming value is not "None" ? > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---
