Can `sqlalchemy.orm.validates` be set on multiple attributes?

183 views
Skip to first unread message

niuji...@gmail.com

unread,
Sep 3, 2021, 4:07:42 PM9/3/21
to sqlalchemy
In the official documentation it says:


validates(*names, **kw)


Decorate a method as a ‘validator’ for one or more named properties.



I need to validate two incoming *-**attributes at the same time,  for example:


class Entity(Base):

    ....

    attr_timezone = Column(String)

    attr_timestamp = Column(MyTimeStamp)


When taking incoming arguments, `attr_timezone` as a string need to be first validated and converted to timezone instance before being attached to my custom class `MyTimeStamp`. Can `validates` do this?

Mike Bayer

unread,
Sep 4, 2021, 10:43:24 AM9/4/21
to noreply-spamdigest via sqlalchemy
its not a simple yes or no because the use case does not totally make sense.

what happens if someone does this:

some_entity().attr_timestamp = <some timestmap>

and then nothing else?  what do you want to happen when that attribute set occurs?


what you probably want to do is require that one or the other attribute is set first.   you can certainly use @validates to set this up, it's just an event hook.

more realistically though in the most practical sense, you'd want to have a method that clearly documents what needs to be done:

class Entity:
   def set_timestamp(self, timestamp, timezone):
       # ...


then make "attr_timestamp" and "attr_timezone" private.     This is boring and not magical but if I were in a large organization where we just need it to be clear and unambigious, this is how I'd do it.






--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
 
 
To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description.
---
You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+...@googlegroups.com.

niuji...@gmail.com

unread,
Oct 1, 2021, 5:04:24 PM10/1/21
to sqlalchemy

Hi Mike,

Instead of this:

class Entity:
   def set_timestamp(self, timestamp, timezone):
       # ...

which you have to manually call it to set, I'd like to have an automated setting directly on initiation, so that I can create new records in a more uniformed ways:
Entity(**params_from_web_form)


Now I just tried using @hybrid_property.setter:
class Tutorsession(Base):
  ...
  @start_time_local.setter
  def start_time_local(self, value):
      timezone_stamp = json.loads(cherrypy.request.body.read())['timezone_stamp']
      self.start_time = create_timestamp(value, timezone_stamp)



unfortunately it gives me an error:

TypeError: 'start_time_local' is an invalid keyword argument for Turtorsession




Is hybrid_property.setter allowed to create new records like this way at all?

Mike Bayer

unread,
Oct 1, 2021, 5:29:52 PM10/1/21
to noreply-spamdigest via sqlalchemy
sure it's just a setter, it seems like you are passing "start_time_local" to your constructor, the ORM does not automatically add hybrid properties to the constructor so you would need to imlpement the __init__ method manually.
Reply all
Reply to author
Forward
0 new messages