2017-12-08 35 views
0

ホストの移行中です。新しいホストでは、より新しいバージョンのMySQLを使用します。これは受け入れるdatetime値の形式が厳密です。私はこれを無効にすることができることを知っていますが、これらの値を適切な形式に正しく変換するソリューションを探したいと思います。私は更新する必要がある多くのモデル(100程度)に簡単にスワップアウトすることができます。Flask-SQLAlchemyのdb.Datetime値を自動的にフォーマットします

これをモデルレベルで更新する方法が見つからない場合は、これらの値が設定されている数千の場所を検索する必要があります。

私はここでの例のモデルをトリムダウンしました

class Timesheet(BaseModel, db.Model): 
    __tablename__ = "timesheet" 
    timesheet_id = db.Column(db.Integer, primary_key=True) 
    created = db.Column(db.DateTime, default=datetime.utcnow) 
    updated = db.Column(db.DateTime) 
    employee_id = db.Column(db.Integer, db.ForeignKey('user.employee_id')) 
    description = db.Column(db.String(255)) 
    hours = db.Column(db.Numeric(9, 2)) 
    billable = db.Column(db.Boolean, default=False) 
    retainer = db.Column(db.Boolean, default=False) 
    client_id = db.Column(db.Integer, db.ForeignKey('client.client_id'), default=None) 
    project_id = db.Column(db.Integer, db.ForeignKey('project.project_id'), default=None) 
    task_id = db.Column(db.Integer, default=None) 
    timesheet_date = db.Column(db.DateTime, default=datetime.utcnow) 

私はISO8601日時の文字列を提供する場合、それは真のPythonのdatetimeオブジェクトを返すようにdb.Datetimeを変更する方法がある願っています( 'YYYY-MM-DDT00:00:00.000Z')

はの線に沿って何かを探して::カラム定義は、その後に変更されるだろう

class FormattedDateTime(db.DateTime): 
    def self.__set__(self, value): 
     return dateutil.parser.parse(value) 
updated = db.Column(FormattedDateTime) 

... SQLAlchemyがMySQLに送信するときに正しい形式で自動的に保存されるようにします。

私はミックスインを見て、これを達成するアプローチを探しましたが、良い解決策を見つけることはできません。ヘルプは非常に感謝しています。

UPDATED: この私がこれまで働いてきたものの草稿が...クエリのフィールドに比較/フィルタリングする際にもうまくやっているようだが、うまくまだテストされていないです。私はビルトインのDateTimeタイプ驚い

class TFDateTime(TypeDecorator): 
    impl = DATETIME 

    def process_bind_param(self, value, dialect): 
     if value is None: 
      return None 
     print("process_bind_param", value, type(value)) 
     if type(value) == datetime or type(value) == date: 
      return value 
     elif type(value) == str: 
      return parse(value, ignoretz=True) 
     else: 
      return None 

    def process_result_value(self, value, dialect): 
     if value is None: 
      return None 
     print("process_result_value", value, type(value)) 
     return value 

答えて

1

は自動的にDBに有効な値を与えるものではありません - それは、SQLAlchemyのバグかもしれませんか?

カスタム型を作成することは、おそらくあなたがやりたいだろう、と述べた - そこfew examples in the SQLAlchemy docsだが、このようなものは、あなたが始める必要があります。

import datetime 
from sqlalchemy.types import TypeDecorator, TIMESTAMP 
import iso8601 

class ISO8601DateTime(TypeDecorator): 
    impl = TIMESTAMP 

    def process_bind_param(self, value, dialect): 
     if value is None: 
      return None 

     if isinstance(value, datetime.datetime): 
      return value.strftime(<iso8601-format-string>) 

     return value 

    def process_result_value(self, value, dialect): 
     if value is None: 
      return None 

     return iso8601.parse_date(value) 

date-utilが必要になることがあり、簡潔にするためにiso8601のlibを使用しますが。また、タイムスタンプ/日時には、方言固有の型を使用する必要があります。

+0

これは本当に私が探しているものに近いですが、自分の価値を8601にしようとはしませんが、ISO 8601であれば、python datetimeオブジェクトに正しく変換して、質問を編集する必要があります私がこれまでにやったことは... – LegendaryJLD

関連する問題