Thanks so much for the detailed answer Mike, and for the quick fix! You're
the best.

On Thu, Jun 27, 2019 at 7:13 PM Mike Bayer <mike...@zzzcomputing.com> wrote:

>
>
> On Thu, Jun 27, 2019, at 12:02 PM, Charles-Axel Dein wrote:
>
> Hi,
>
> I'm trying to have a deleted_at column on my records. I use MySQL and
> latest sqlalchemy as of writing. For historical reasons, I want to keep
> using the MySQL's TIMESTAMP columns.
>
> I would like to use timezone-aware datetime throughout my codebase.
> Everything in my DB is stored as UTC, so I don't really need to store the
> timezone. I just want to make sure the datetime is returned as a
> UTC-datetime.
>
> import pytz
> from sqlalchemy import Column, text, types
> from sqlalchemy.dialects.mysql import TIMESTAMP as M_TIMESTAMP
>
>
> # Fractional second precision
> FSP = 6
> TIMESTAMP = M_TIMESTAMP(fsp=FSP)
> CURRENT_TIMESTAMP = text("CURRENT_TIMESTAMP(%d)" % FSP)
>
>
> class TimezoneAwareTimestamp(types.TypeDecorator):
>     """Ensure tz-aware timestamp are returned."""
>
>
>     impl = TIMESTAMP
>
>
>     def process_result_value(self, value, dialect):
>         if not value:
>             return None
>         return value.replace(tzinfo=pytz.UTC)
>
>
> def DeletedAt():
>     return Column("deleted_at", TimezoneAwareTimestamp, server_onupdate=
> text("0"),
>                   nullable=True)
>
>
> This is a pretty natural solution I came up with. Problem:
> TimezoneAwareTimestamp does not respect the `server_onupdate` attribute on
> creation. A table created with this DeletedAt column will show up as:
>
> deleted_at` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE
> CURRENT_TIMESTAMP(6)
>
>
> So you need to instead be looking at the DDL that's being emitted and not
> the "SHOW CREATE TABLE" which I assume is what's above.
>
> "server_onupdate" does *not* generate any DDL, as there is no such thing
> as "ON UPDATE" in SQL; this is a MySQL-specific extension that I believe
> only applies to their TIMESTAMP datatype in the first place.
>
> Support for MySQL's "ON UPDATE" phrase is not included as a first class
> feature in SQLAlchemy right now and
> https://github.com/sqlalchemy/sqlalchemy/issues/4652 seeks to add this
> functionality.   However a widely used workaround is to apply the "ON
> UPDATE" inside the "server_default" field, which *is* part of standard SQL,
> e.g. server_default=text("DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP") or
> whatever you want it to be.
>
> as for the nullable part, you've unfortunately found a bug, in that the
> TypeDecorator is preventing it from detecting the special case nullability
> for TIMESTAMP.  It will be fixed in about 90 minutes
> https://github.com/sqlalchemy/sqlalchemy/issues/4743 but a new SQLAlchemy
> release isn't for a couple of weeks most likely.    For now what I would do
> is add an "ALTER TABLE" command in a textual way to your metadata, and you
> can make whatever result you'd like occur here:
>
> class A(Base):
>     __tablename__ = 'a'
>
>     id = Column(Integer, primary_key=True)
>     data = DeletedAt()
>
> event.listen(
>     A.__table__,
>     'after_create',
>     DDL(
>         "ALTER TABLE a MODIFY deleted_at TIMESTAMP NULL "
>         "DEFAULT NULL ON UPDATE
> CURRENT_TIMESTAMP").execute_if(dialect="mysql")
> )
>
>
> the ALTER will fire off after the CREATE TABLE.
>
>
>
>
>
>
>
>
>
>
>
> instead of (replacing TimezoneAwareTimestamp with TIMESTAMP):
>
> deleted_at` timestamp(6) NULL DEFAULT NULL
>
> How can I have the custom type respect server_onupdate and nullable?
>
> Thanks,
>
> Charles
>
>
> --
> SQLAlchemy -
> The Python SQL Toolkit and Object Relational Mapper
>
> http://www.sqlalchemy.org/
>
> 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+unsubscr...@googlegroups.com.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sqlalchemy/983a49db-ae3f-422a-b996-b176f76c5aa7%40googlegroups.com
> <https://groups.google.com/d/msgid/sqlalchemy/983a49db-ae3f-422a-b996-b176f76c5aa7%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> SQLAlchemy -
> The Python SQL Toolkit and Object Relational Mapper
>
> http://www.sqlalchemy.org/
>
> 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+unsubscr...@googlegroups.com.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sqlalchemy/2aaaf338-42a3-4afe-95e6-d3de492b7c8e%40www.fastmail.com
> <https://groups.google.com/d/msgid/sqlalchemy/2aaaf338-42a3-4afe-95e6-d3de492b7c8e%40www.fastmail.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

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+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/CAAN9J6r5uhzjRyQuuqqHT%2B8HN-3Q7%2BPYUTgoLPKSWOCBypLfTw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to