2017-08-15 31 views
0

我創建了具有帶時區dateTime的列的表。 在我model.py不正確的時區打入db

DATABASE=> \d messages 
            Table "public.messages" 
    Column |   Type   |       Modifiers       
-----------+-----------------------+----------------------------------------------------------- 
msg_id | integer    | not null default nextval('messages_msg_id_seq'::regclass) 
fullName | character varying(60) | 
message | character varying  | 
email  | character varying  | 
visitorId | character varying(10) | 
done  | boolean    | 
pub_date | time with time zone | 

不管時區似乎什麼時區/日期時間我使用:

db = SQLAlchemy(app) 

class Messages(db.Model): 
    __tablename__ = 'messages' 
    msgId = db.Column('msg_id', db.Integer, primary_key=True) 
    fullName = db.Column(db.String(60)) 
    message = db.Column(db.String) 
    email = db.Column(db.String, unique=True) 
    visitorId = db.Column(db.String(10)) 
    done = db.Column(db.Boolean) 
    pub_date = db.Column(types.Time(timezone=True)) 

    def __init__(self, fullName, email, message, visitorId, submitTime): 
     self.fullName = fullName 
     self.email = email 
     self.message = message 
     self.visitorId = visitorId 
     self.done = False 
     self.pub_date = submitTime 

而且我一直在使用db.create_all()heroku pg:psql,下面導致創建的表衝擊+00這是UTC。

4 | ciasto  | testing |   | 9IQVW1K6W | f | 15:48:31.784704+00 

爲什麼會發生這種情況?

我路過的時候爲使用應該從下面經過正確dtWithZone PostgreSQL的表信息下面路由功能pub_date

@app.route('/newmsg', methods=['GET', 'POST']) 
def newmsg(): 
    form = _appforms.MessagingForm() 
    if form.validate_on_submit(): 
     name = request.form['fullName'] 
     ip = request.access_route[0] # gives ip address of the visitor 
     unique_visitor_id = request.cookies.get("unique_visitor") 

     data = _utils.getJsonFromURL("http://ip-api.com/json/{}".format(ip)) 
     tz = "Asia/Kolkata" 
     if data["status"] == "success": 
      tz = data["timezone"] 

     flash("Your IP is {} and you are visiting this site from {} timezone.".format(ip, tz)) 

     dtWithZone = datetime.datetime.now(pytz.timezone(tz)) 
     msg = Messages(name, request.form['email'], request.form['message'], unique_visitor_id, dtWithZone) 
     _db.session.add(msg) 
     _db.session.commit() 
     msg = "Thank you, {}".format(name) 
     return render_template('thankyou.html', form=form, msg=msg) 
    return render_template('newMessage.html', form=form, title=" | Messaging", msg="Write your message") 

但是這是我的本地計算機上正常工作,看着表條目我可以看到:

8 | tester | local teasing |   | NV33A1L66 | f | 21:09:24.804903+05:30 
+0

不是MySQL的。已移除標記。 –

回答

0

所以這裏的一對時區雅一個簡短的教程。要查看時區PostgreSQL有在其內部時區信息數據庫,運行此查詢:

select * from pg_timezone_names ; 
(edited list) 
       name    | abbrev | utc_offset | is_dst 
----------------------------------+--------+------------+-------- 
America/Denver     | MDT | -06:00:00 | t 
America/Phoenix     | MST | -07:00:00 | f 
America/New_York     | EDT | -04:00:00 | t 
America/Chicago     | CDT | -05:00:00 | t 
America/Los_Angeles    | PDT | -07:00:00 | t 

而這裏的設置TZ和插入時間戳的例子:

create table tztest (ts timestamptz, tz text); 
set timezone="America/New_York"; 
insert into tztest values ('2017-01-10 12:00:00','America/New_York'); 
set timezone='America/Chicago'; 
insert into tztest values ('2017-01-10 12:00:00','America/Chicago'); 
set timezone='America/Denver'; 
insert into tztest values ('2017-01-10 12:00:00','America/Denver'); 
set timezone='America/Phoenix'; 
insert into tztest values ('2017-01-10 12:00:00','America/Phoenix'); 
set timezone='America/Los_Angeles'; 
insert into tztest values ('2017-01-10 12:00:00','America/Los_Angeles') 
select * from tztest ; 
      ts   |   tz 
------------------------+--------------------- 
2017-01-10 09:00:00-08 | America/New_York 
2017-01-10 10:00:00-08 | America/Chicago 
2017-01-10 11:00:00-08 | America/Denver 
2017-01-10 11:00:00-08 | America/Phoenix 
2017-01-10 12:00:00-08 | America/Los_Angeles 

注意的是,雖然LA被列爲具有-07:00:00抵消,現在不是夏天,所以現在是1月份的-08:00:00。

若要查看實際存儲時間戳,時區設置爲UTC:

set timezone='UTC'; 
select * from tztest ; 
      ts   |   tz 
------------------------+--------------------- 
2017-01-10 17:00:00+00 | America/New_York 
2017-01-10 18:00:00+00 | America/Chicago 
2017-01-10 19:00:00+00 | America/Denver 
2017-01-10 19:00:00+00 | America/Phoenix 
2017-01-10 20:00:00+00 | America/Los_Angeles 
+1

謝謝mucho gracias .. –

+0

任何時間!時區數學很古怪,所以這是我總是讓數據庫處理,如果可能的話。 –

+1

有另一列只是爲了存儲時區不傷害所以我添加了一個新的列只是爲了在我的項目中存儲用戶時區。 –

1

想通了自己, since PostgreSQL timezone aware, if we punch datetime with timezone it converts it to PostgreSQL local timezone , so on heroku it is set to UTC so it was always getting converted to UTC format, so I converted the column pub_datedb.String(24)和保存日期/時間/與TI mezone作爲字符串。這工作完美。

更新消息:

首先定義具有列表,其接受與日期時間時區:

的src/model.py

from sqlalchemy import MetaData 
from sqlalchemy import create_engine 
from sqlalchemy import DateTime 

db = SQLAlchemy(app) 

class Messages(db.Model): 
    __tablename__ = 'messages' 
    msgId = db.Column('msg_id', db.Integer, primary_key=True) 
    fullName = db.Column(db.String(60)) 
    message = db.Column(db.String) 
    email = db.Column(db.String, unique=True) 
    visitorId = db.Column(db.String(10)) 
    done = db.Column(db.Boolean) 
    pub_date = db.Column(DateTime(timezone=True)) 

然後從蟒終端:運行from src.model import db; db.create_all() 這將在prope中創建postgresql中的表列類型/名稱。 則有以下功能連接到PostgreSQL的使用用戶時區:

def insertIntoTable(dtWithZone, tableName, columValues): 
    db_uri = "postgresql://localhost/messages" 
    engine = create_engine(db_uri, connect_args={"options": "-c timezone={}".format(dtWithZone.timetz().tzinfo.zone)}) 
    meta = MetaData(engine, reflect=True) 
    table = meta.tables[tableName] 
    ins = table.insert().values(**columValues) 
    conn = engine.connect() 
    conn.execute(ins) 
    conn.close() 

完蛋了!

現在從路由功能,我做了以下變化:

@app.route('/newmsg', methods=['GET', 'POST']) 
def newmsg(): 
    form = _appforms.MessagingForm() 
    # if form.validate_on_submit(): 
    if request.method == "POST": 
     ip = request.access_route[0] 
     data = _utils.getJsonFromURL("http://ip-api.com/json/{}".format(ip)) 
     tz = "Pacific/America" 
     if data["status"] == "success": 
      tz = data.get("timezone") 

     dtWithZone = datetime.datetime.now(pytz.timezone(tz)) 
     name = request.form.get('fullName', "") 
     columValues = { 
     'pub_date' : dtWithZone, 
     'fullName' : name, 
     'visitorId': request.cookies.get("unique_visitor", ""), 
     'message' : request.form.get('message', ""), 
     'email' : request.form.get('email', "") 
     } 

     insertIntoTable(dtWithZone, 'messages', columValues) 
     msg = "Thank you, {}".format(name) 
     return render_template('thankyou.html', form=form, msg=msg) 
    return render_template('newMessage.html', form=form, title=" | Messaging", msg="Write your message") 

完美的作品(Y)

+0

您還可以設置每個連接的時區,這將覆蓋postgresql的內部時區。此外,您還可以在「時區tznamehere」處說明它所在的時區。 處理文本中的日期/時間戳是一種很好的方式,可以通過改變時區偏移(如夏時制時間等)來糾正錯誤。 –

+0

您的意思是說每個連接我執行一個查詢'SET TIMEZONE TO'時區的用戶';'? –

+0

你也可以做一些像alter user,alter database等的東西來讓這些東西粘住。 –