Note that there are some explanatory texts on larger screens.

plurals
  1. POSQLAlchemy DateTime timezone
    primarykey
    data
    text
    <p>SQLAlchemy's <code>DateTime</code> type allows for a <code>timezone=True</code> argument to save a non-naive datetime object to the database, and to return it as such. Is there any way to modify the timezone of the <code>tzinfo</code> that SQLAlchemy passes in so it could be, for instance, UTC? I realize that I could just use <code>default=datetime.datetime.utcnow</code>; however, this is a naive time that would happily accept someone passing in a naive localtime-based datetime, even if I used <code>timezone=True</code> with it, because it makes local or UTC time non-naive without having a base timezone to normalize it with. I have tried (using <a href="http://pytz.sourceforge.net/" rel="nofollow noreferrer">pytz</a>) to make the datetime object non-naive, but when I save this to the DB it comes back as naive.</p> <p>Note how datetime.datetime.utcnow does not work with <code>timezone=True</code> so well:</p> <pre><code>import sqlalchemy as sa from sqlalchemy.sql import select import datetime metadata = sa.MetaData('postgres://user:pass@machine/db') data_table = sa.Table('data', metadata, sa.Column('id', sa.types.Integer, primary_key=True), sa.Column('date', sa.types.DateTime(timezone=True), default=datetime.datetime.utcnow) ) metadata.create_all() engine = metadata.bind conn = engine.connect() result = conn.execute(data_table.insert().values(id=1)) s = select([data_table]) result = conn.execute(s) row = result.fetchone() </code></pre> <blockquote> <p>(1, datetime.datetime(2009, 1, 6, 0, 9, 36, 891887))</p> </blockquote> <pre><code>row[1].utcoffset() </code></pre> <blockquote> <p>datetime.timedelta(-1, 64800) # that's my localtime offset!!</p> </blockquote> <pre><code>datetime.datetime.now(tz=pytz.timezone("US/Central")) </code></pre> <blockquote> <p>datetime.timedelta(-1, 64800)</p> </blockquote> <pre><code>datetime.datetime.now(tz=pytz.timezone("UTC")) </code></pre> <blockquote> <p>datetime.timedelta(0) #UTC</p> </blockquote> <p>Even if I change it to explicitly use UTC:</p> <p>...</p> <pre><code>data_table = sa.Table('data', metadata, sa.Column('id', sa.types.Integer, primary_key=True), sa.Column('date', sa.types.DateTime(timezone=True), default=datetime.datetime.now(tz=pytz.timezone('UTC'))) ) row[1].utcoffset() </code></pre> <p>...</p> <blockquote> <p>datetime.timedelta(-1, 64800) # it did not use the timezone I explicitly added</p> </blockquote> <p>Or if I drop the <code>timezone=True</code>:</p> <p>...</p> <pre><code>data_table = sa.Table('data', metadata, sa.Column('id', sa.types.Integer, primary_key=True), sa.Column('date', sa.types.DateTime(), default=datetime.datetime.now(tz=pytz.timezone('UTC'))) ) row[1].utcoffset() is None </code></pre> <p>...</p> <blockquote> <p>True # it didn't even save a timezone to the db this time</p> </blockquote>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload