SQLAlchemy Validates decorator on multiple attributes












0














I have used a sqlalchemy validator decorator on two of my attributes as follows:



@validates('start_time', 'duration')
def validate_times(self, key, value):
if self.obj:
# then attached object is not transient under creation, so we can validate

# validate start time
if self.start_time < self.obj.start_time:
raise IntegrityError('item start time is before the obj start time', None, None)

# validate end time
if self.start_time + dt.timedelta(minutes=self.duration) > self.obj.end_time:
raise IntegrityError('item end time is after the obj end time', None, None)
return value


Basically there is a second database obj (a sort of parent obj) which has start and end times and the point of this validation is to ensure that the start and end times of this specific item are within those of its attached parent.



This is a fairly safe approach in that I do not believe it breaks integrity, but since the order of attribute validation is random it can potentially raise IntegrityError even when there should be none. I.e. it does not generate false negatives, but potentially can generate false positives.



Consider the following case:



before amend:



obj.start_time = 0
obj.end_time = 10
item.start_time = 8
item.duration = 1 # -> implied end_time is 9 and all lies between 0<8<9<10.


amend to:



obj.start_time = 0
obj.end_time = 10
item.start_time = 2
item.duration = 3 # -> implied end_time is 5 and is valid since 0<2<5<10


However, it doesn't validate simultaneously, but sequentially, so
if duration is validated first it will result in an error since (old_8+new_3 = 11 > 10). But in this case if start_time is validated first it will be OK.
Obviously there are case examples where the problem might arise in reverse order.



Are there better solutions?










share|improve this question
























  • There is no way for the validator to know if the other value is right or wrong at the time. The easiest thing I can think of would be to have an item.end_time instead of duration, then just compare obj.start_time to item.start_time and obj.end_time to item.end_time, if any one of them are out - you have trouble. Or, you could have a item.amend_time(start_time, duration) method as it could be sure about the validity of both args.This isn't really a sqlalchemy issue though as the validator is called when the attribute is changed, the order of which is governed by your application.
    – SuperShoot
    Nov 21 '18 at 13:01
















0














I have used a sqlalchemy validator decorator on two of my attributes as follows:



@validates('start_time', 'duration')
def validate_times(self, key, value):
if self.obj:
# then attached object is not transient under creation, so we can validate

# validate start time
if self.start_time < self.obj.start_time:
raise IntegrityError('item start time is before the obj start time', None, None)

# validate end time
if self.start_time + dt.timedelta(minutes=self.duration) > self.obj.end_time:
raise IntegrityError('item end time is after the obj end time', None, None)
return value


Basically there is a second database obj (a sort of parent obj) which has start and end times and the point of this validation is to ensure that the start and end times of this specific item are within those of its attached parent.



This is a fairly safe approach in that I do not believe it breaks integrity, but since the order of attribute validation is random it can potentially raise IntegrityError even when there should be none. I.e. it does not generate false negatives, but potentially can generate false positives.



Consider the following case:



before amend:



obj.start_time = 0
obj.end_time = 10
item.start_time = 8
item.duration = 1 # -> implied end_time is 9 and all lies between 0<8<9<10.


amend to:



obj.start_time = 0
obj.end_time = 10
item.start_time = 2
item.duration = 3 # -> implied end_time is 5 and is valid since 0<2<5<10


However, it doesn't validate simultaneously, but sequentially, so
if duration is validated first it will result in an error since (old_8+new_3 = 11 > 10). But in this case if start_time is validated first it will be OK.
Obviously there are case examples where the problem might arise in reverse order.



Are there better solutions?










share|improve this question
























  • There is no way for the validator to know if the other value is right or wrong at the time. The easiest thing I can think of would be to have an item.end_time instead of duration, then just compare obj.start_time to item.start_time and obj.end_time to item.end_time, if any one of them are out - you have trouble. Or, you could have a item.amend_time(start_time, duration) method as it could be sure about the validity of both args.This isn't really a sqlalchemy issue though as the validator is called when the attribute is changed, the order of which is governed by your application.
    – SuperShoot
    Nov 21 '18 at 13:01














0












0








0







I have used a sqlalchemy validator decorator on two of my attributes as follows:



@validates('start_time', 'duration')
def validate_times(self, key, value):
if self.obj:
# then attached object is not transient under creation, so we can validate

# validate start time
if self.start_time < self.obj.start_time:
raise IntegrityError('item start time is before the obj start time', None, None)

# validate end time
if self.start_time + dt.timedelta(minutes=self.duration) > self.obj.end_time:
raise IntegrityError('item end time is after the obj end time', None, None)
return value


Basically there is a second database obj (a sort of parent obj) which has start and end times and the point of this validation is to ensure that the start and end times of this specific item are within those of its attached parent.



This is a fairly safe approach in that I do not believe it breaks integrity, but since the order of attribute validation is random it can potentially raise IntegrityError even when there should be none. I.e. it does not generate false negatives, but potentially can generate false positives.



Consider the following case:



before amend:



obj.start_time = 0
obj.end_time = 10
item.start_time = 8
item.duration = 1 # -> implied end_time is 9 and all lies between 0<8<9<10.


amend to:



obj.start_time = 0
obj.end_time = 10
item.start_time = 2
item.duration = 3 # -> implied end_time is 5 and is valid since 0<2<5<10


However, it doesn't validate simultaneously, but sequentially, so
if duration is validated first it will result in an error since (old_8+new_3 = 11 > 10). But in this case if start_time is validated first it will be OK.
Obviously there are case examples where the problem might arise in reverse order.



Are there better solutions?










share|improve this question















I have used a sqlalchemy validator decorator on two of my attributes as follows:



@validates('start_time', 'duration')
def validate_times(self, key, value):
if self.obj:
# then attached object is not transient under creation, so we can validate

# validate start time
if self.start_time < self.obj.start_time:
raise IntegrityError('item start time is before the obj start time', None, None)

# validate end time
if self.start_time + dt.timedelta(minutes=self.duration) > self.obj.end_time:
raise IntegrityError('item end time is after the obj end time', None, None)
return value


Basically there is a second database obj (a sort of parent obj) which has start and end times and the point of this validation is to ensure that the start and end times of this specific item are within those of its attached parent.



This is a fairly safe approach in that I do not believe it breaks integrity, but since the order of attribute validation is random it can potentially raise IntegrityError even when there should be none. I.e. it does not generate false negatives, but potentially can generate false positives.



Consider the following case:



before amend:



obj.start_time = 0
obj.end_time = 10
item.start_time = 8
item.duration = 1 # -> implied end_time is 9 and all lies between 0<8<9<10.


amend to:



obj.start_time = 0
obj.end_time = 10
item.start_time = 2
item.duration = 3 # -> implied end_time is 5 and is valid since 0<2<5<10


However, it doesn't validate simultaneously, but sequentially, so
if duration is validated first it will result in an error since (old_8+new_3 = 11 > 10). But in this case if start_time is validated first it will be OK.
Obviously there are case examples where the problem might arise in reverse order.



Are there better solutions?







python postgresql sqlalchemy flask-sqlalchemy






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 '18 at 9:04







Attack68

















asked Nov 20 '18 at 14:30









Attack68Attack68

1,0081411




1,0081411












  • There is no way for the validator to know if the other value is right or wrong at the time. The easiest thing I can think of would be to have an item.end_time instead of duration, then just compare obj.start_time to item.start_time and obj.end_time to item.end_time, if any one of them are out - you have trouble. Or, you could have a item.amend_time(start_time, duration) method as it could be sure about the validity of both args.This isn't really a sqlalchemy issue though as the validator is called when the attribute is changed, the order of which is governed by your application.
    – SuperShoot
    Nov 21 '18 at 13:01


















  • There is no way for the validator to know if the other value is right or wrong at the time. The easiest thing I can think of would be to have an item.end_time instead of duration, then just compare obj.start_time to item.start_time and obj.end_time to item.end_time, if any one of them are out - you have trouble. Or, you could have a item.amend_time(start_time, duration) method as it could be sure about the validity of both args.This isn't really a sqlalchemy issue though as the validator is called when the attribute is changed, the order of which is governed by your application.
    – SuperShoot
    Nov 21 '18 at 13:01
















There is no way for the validator to know if the other value is right or wrong at the time. The easiest thing I can think of would be to have an item.end_time instead of duration, then just compare obj.start_time to item.start_time and obj.end_time to item.end_time, if any one of them are out - you have trouble. Or, you could have a item.amend_time(start_time, duration) method as it could be sure about the validity of both args.This isn't really a sqlalchemy issue though as the validator is called when the attribute is changed, the order of which is governed by your application.
– SuperShoot
Nov 21 '18 at 13:01




There is no way for the validator to know if the other value is right or wrong at the time. The easiest thing I can think of would be to have an item.end_time instead of duration, then just compare obj.start_time to item.start_time and obj.end_time to item.end_time, if any one of them are out - you have trouble. Or, you could have a item.amend_time(start_time, duration) method as it could be sure about the validity of both args.This isn't really a sqlalchemy issue though as the validator is called when the attribute is changed, the order of which is governed by your application.
– SuperShoot
Nov 21 '18 at 13:01












0






active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53395231%2fsqlalchemy-validates-decorator-on-multiple-attributes%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53395231%2fsqlalchemy-validates-decorator-on-multiple-attributes%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

"Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

Alcedinidae

Origin of the phrase “under your belt”?