SQLAlchemy Validates decorator on multiple attributes
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
add a comment |
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
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 anitem.end_time
instead of duration, then just compareobj.start_time
toitem.start_time
andobj.end_time
toitem.end_time
, if any one of them are out - you have trouble. Or, you could have aitem.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
add a comment |
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
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
python postgresql sqlalchemy flask-sqlalchemy
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 anitem.end_time
instead of duration, then just compareobj.start_time
toitem.start_time
andobj.end_time
toitem.end_time
, if any one of them are out - you have trouble. Or, you could have aitem.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
add a comment |
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 anitem.end_time
instead of duration, then just compareobj.start_time
toitem.start_time
andobj.end_time
toitem.end_time
, if any one of them are out - you have trouble. Or, you could have aitem.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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 compareobj.start_time
toitem.start_time
andobj.end_time
toitem.end_time
, if any one of them are out - you have trouble. Or, you could have aitem.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