Another option would be to have separate columns for date and time, and leave the time column NULL when it's not present.
If you still want to store it as a string, I guess you'll need to try parsing it as a datetime and then fall back to parsing it as a date. You haven't said what database you are using, but for MySQL it might be something like this: IFNULL(STR_TO_DATE(timepoint, <your-datetime-format>), STR_TO_DATE(timepoint, <your-date-format>)) If you're not actually going to filter on these columns, I don't think I'd do any of this at all. Instead, I'd use something like a TypeDecorator to convert the values when loading from and saving to the database. Simon On Fri, Sep 16, 2016 at 9:53 AM, Jinghui Niu <niujing...@gmail.com> wrote: > If I store the as DateTime values and with a second column to indicate > whether it's a date or datetime, it would look like this for a Date: > col1: "2016-09-16 00:00:00", col2: "date only" > > It looks so messy to me:) > > I'd prefer to have Date and DateTime distinctively written in my database. I > admit that it's one of my personal preference though:) > > On Fri, Sep 16, 2016 at 1:49 AM, Jinghui Niu <niujing...@gmail.com> wrote: >> >> Thanks for reply. >> >> The reason is simple. I plan in the future to accommodate datetime range >> into that column as well, so storing this logic as plain strings gives the >> most flexibility. This is a project that I'm learning by making. So I would >> like to try all the new features for later tasks. >> >> I'm fascinated by hybrid_property, but is stuck now when trying to >> dispatch functions at the SQL expression level. >> >> Jinghui >> >> On Fri, Sep 16, 2016 at 1:34 AM, Simon King <si...@simonking.org.uk> >> wrote: >>> >>> Ignore SQLAlchemy for the moment and describe what you are trying to >>> achieve. It looks like you want to store dates and times as strings in >>> your database (rather than the appropriate type), and yet still be >>> able to perform date-related operations on them qhen querying. Is that >>> right? Is there a reason why you can't store them as proper DateTime >>> values (perhaps with a second column to indicate whether or not the >>> time part is valid)? >>> >>> Simon >>> >>> On Fri, Sep 16, 2016 at 4:39 AM, Jinghui Niu <niujing...@gmail.com> >>> wrote: >>> > I have the following code snippet, I marked my question in a comment >>> > line >>> > inside the hybrid_property.expression part. As you can see, it is now >>> > not >>> > implemented: >>> > >>> > from sqlalchemy.ext.declarative import declared_attr >>> > from sqlalchemy import Column, Integer, String, Unicode, UnicodeText >>> > from sqlalchemy.ext.hybrid import hybrid_property, hybrid_method >>> > import arrow >>> > >>> > >>> > datetimeString_format = { >>> > "UTC": "%Y-%m-%d %H:%M:%S+00:00", >>> > "local_with_timezoneMarker": "%Y-%m-%d %H:%M:%S %Z", >>> > "local_without_timezoneMarker": "%Y-%m-%d %H:%M:%S" >>> > } >>> > >>> > >>> > dateString_format = "%Y-%m-%d" >>> > >>> > >>> > class My_TimePoint_Mixin: >>> > # define output formats: >>> > datetimeString_inUTC_format = "%Y-%m-%d %H:%M:%S+00:00" >>> > datetimeString_naive_format = "%Y-%m-%d %H:%M:%S" >>> > >>> > >>> > # instrumented fields: >>> > _TimePoint_in_database = Column('timepoint', String, >>> > nullable=False) >>> > _TimePoint_in_database_suffix = Column( >>> > 'timepoint_suffix', String, nullable=False) >>> > >>> > >>> > @hybrid_property >>> > def timepoint(self): >>> > twoPossibleType_handlers = [ >>> > self._report_ACCRT_DATE, >>> > self._report_ACCRT_DATETIME >>> > ] >>> > for handler in twoPossibleType_handlers: >>> > print("handler: ", handler) >>> > try: >>> > return handler(self) >>> > except (AssertionError, ValueError) as e: >>> > logging.warning("Try next handler!") >>> > >>> > @timepoint.expression >>> > def timepoint(cls): >>> > pass >>> > # How can I implement SQL expression for a equivalent function >>> > dispatch here? There seems to be no SQL equivalent structure for this? >>> > >>> > >>> > @timepoint.setter >>> > def timepoint(self, datetimepointOBJ): >>> > handlers_lookup = { >>> > datetime.datetime: self._set_ACCRT_DATETIME, >>> > datetime.date: self._set_ACCRT_DATE >>> > } >>> > this_time = type(datetimepointOBJ) >>> > this_handler = handlers_lookup[this_time] >>> > print("handler: ", this_handler) >>> > this_handler(datetimepointOBJ) >>> > >>> > >>> > def _report_ACCRT_DATE(self): >>> > """Accurate Date""" >>> > assert self._TimePoint_in_database_suffix == "ACCRT_DATE" >>> > date_string = self._TimePoint_in_database >>> > dateString_format = "%Y-%m-%d" >>> > # return a datetime.date >>> > return datetime.datetime.strptime(date_string, >>> > dateString_format).date() >>> > >>> > >>> > def _report_ACCRT_DATETIME(self): >>> > """Accurate DateTime""" >>> > assert self._TimePoint_in_database_suffix in >>> > pytz.all_timezones_set >>> > datetimeString_inUTC = self._TimePoint_in_database >>> > utc_naive = datetime.datetime.strptime( >>> > datetimeString_inUTC, self.datetimeString_inUTC_format) >>> > utc_timepoint = arrow.get(utc_naive, "utc") >>> > # localize >>> > local_timepoint = >>> > utc_timepoint.to(self._TimePoint_in_database_suffix) >>> > # return a datetime.datetime >>> > return local_timepoint.datetime >>> > >>> > >>> > def _set_ACCRT_DATETIME(self, datetimeOBJ_aware): >>> > assert isinstance(datetimeOBJ_aware, datetime.datetime), "Must >>> > be a >>> > valid datetime.datetime!" >>> > assert datetimeOBJ_aware.tzinfo is not None, "Must contain >>> > tzinfo!" >>> > utctime_aware_arrow = arrow.get(datetimeOBJ_aware).to('utc') >>> > utctime_aware_datetime = utctime_aware_arrow.datetime >>> > store_datetime_string = utctime_aware_datetime.strftime( >>> > self.datetimeString_inUTC_format) >>> > self._TimePoint_in_database = store_datetime_string >>> > >>> > >>> > def _set_ACCRT_DATE(self, dateOBJ): >>> > store_date_string = dateOBJ.isoformat() >>> > self._TimePoint_in_database = store_date_string >>> > >>> > Could someone please point out a clue as to implement the >>> > hybrid_property.expression part? Thanks. >>> > >>> > I've also posted a similar issue on stackoverflow.com, for reference: >>> > >>> > >>> > http://stackoverflow.com/questions/39485440/calling-from-the-same-class-why-is-one-treated-as-bound-method-while-the-other >>> > >>> > -- >>> > 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+unsubscr...@googlegroups.com. >>> > To post to this group, send email to sqlalchemy@googlegroups.com. >>> > Visit this group at https://groups.google.com/group/sqlalchemy. >>> > For more options, visit https://groups.google.com/d/optout. >>> >>> -- >>> You received this message because you are subscribed to a topic in the >>> Google Groups "sqlalchemy" group. >>> To unsubscribe from this topic, visit >>> https://groups.google.com/d/topic/sqlalchemy/i8k2u7bK5x4/unsubscribe. >>> To unsubscribe from this group and all its topics, send an email to >>> sqlalchemy+unsubscr...@googlegroups.com. >>> To post to this group, send email to sqlalchemy@googlegroups.com. >>> Visit this group at https://groups.google.com/group/sqlalchemy. >>> For more options, visit https://groups.google.com/d/optout. >> >> > > -- > 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+unsubscr...@googlegroups.com. > To post to this group, send email to sqlalchemy@googlegroups.com. > Visit this group at https://groups.google.com/group/sqlalchemy. > For more options, visit https://groups.google.com/d/optout. -- 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+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.