'Timestamp isn't a type' により、flutter buildが通らない
Firestoreのタイムスタンプ型をDartのDateTimeに変換する時に、1時間ほどハマってしまったので。
freezed
を使っている人は多いと思いますが、DateTime⇔Timestampを変換するには、以下のようなコンバーターを噛ます必要があります。
class TimestampConverter implements JsonConverter<DateTime, Timestamp> { const TimestampConverter(); @override DateTime fromJson(Timestamp json) => json.toDate(); @override Timestamp toJson(DateTime object) => Timestamp.fromDate(object); }
flutter run
しようとすると、「Timestamp isn't a type」でコケてしまい、Dartのエラーが出ました。型を解決できないって話らしい。xxx.g.dart
でおなじみ、json_serializable
が自動生成したコードで、それが出た。
結論から言えば、xxx.g.dart
の元のクラスで、cloud_firestore.dart
をインポートする必要があった。
import 'package:cloud_firestore/cloud_firestore.dart'; //これがないと型解決できない part 'hoge.freezed.dart'; part 'hoge.g.dart'; @freezed class Hoge with _$Hoge { const factory Hoge({ @TimestampConverter() required DateTime joined, }) = _Hoge; factory Hoge.fromJson(Map<String, dynamic> json) => _$HogeFromJson(json); }
part
で分割されたコードにおいて、解決できない型があっても、Dartがコンパイルエラーにならなかった。そういうもんなのかな。dart:core
にない型なので参照が必要なのはそれはそう、って感じ。
PythonでJSONを任意の型にデコードしたい
How to convert JSON data into a Python object? - Stack Overflow
一番簡単なコードがこれ。
import json
j = json.loads(your_json)
u = User(**j)
こういうモデルを定義して、以下のようなコードを書いてFastAPIに食わせたら、普通に動いた。
from typing import List, Optional from pydantic import BaseModel class Item(BaseModel): item_id: int item_name: str thumbnail: str description: str x_list: Optional[List[str]] maker: Optional[Maker] class Maker(BaseModel): uuid: str name: str furigana: str email: str zipcode: str address: str building: str tel: str fax: str
# fastapi @router.get("/api/item") async def fetch_item(): import os base = os.path.dirname(os.path.abspath(__file__)) with open(f'{base}/json/sample.json') as f: df = json.load(f) result = [Item(**x) for x in df] #これでオブジェクトに型変換できる return result
Next.js のgetStaticPropsのチュートリアルをTypeScriptで
以下の所をTypeScriptで書くとこうなったので、共有。
function Blog({ posts }) { return ( <ul> {posts.map((post) => ( <li>{post.title}</li> ))} </ul> ) } // This function gets called at build time export async function getStaticProps() { // Call an external API endpoint to get posts const res = await fetch('https://.../posts') const posts = await res.json() // By returning { props: { posts } }, the Blog component // will receive `posts` as a prop at build time return { props: { posts, }, } } export default Blog
Visual Studio 2022 17.2系 on ARM Windowsで、IDE固有のバグを2つ踏んだ模様
IDE起因のバグが2つもある。
- Unrecoverable build error - 0x800700C1
- テストが実行されない
- 1週間前動いていたものが、テストが検出されなくなった。
Intel CPUのWindowsでは、最新版(17.2.3)のVS Communityにおいて、上記問題は発生せず。ARMの(M1Pro のParallels) においてのみ。
致命的な問題で、Visual Studio 2022 の Communityはロールバックができない。バージョンを指定して入れ直すことができなくて、有償のエディションだけらしい。なんでよ... JetBrainのToolBox的な機能があれば、本件はすぐ解決するのに。
Visual Studio 2022 Pro の17.1.7 を落として見た所、上記2つの不具合は起こらなかった。17.2 系固有の問題だった。IDEの不具合を踏むのは辛い所だ。
Visual Studio 2022 17.3 Preview 2 リリースで、Arm64 のWindows11がサポートを予定しているようだ。現在は、17.3.1.1 。7月頃かな。頼むぞ。
.NET Framework 4.8 → .NET 6 へ移行作業にトライ
死ぬほど重い腰を上げて、こちらにトライしてみた。そうはいっても、やることは単純だった。下記のUpgrade Assistantに沿って、Enterを叩きまくる簡単なお仕事。Enterを押す回数が多く、20回ぐらい押した。
やってみた所、あっさり.net6でビルドが出来た。PrintDocumentみたいに、Windows固有のAPIを書くと警告が出るようになった。
[SupportedOSPlatform("windows")]
をつけまくるのは辛いので、Windowsしかサポートしないですっていうビルド設定みたいなやつが欲しい。
唯一困った点が、.NET FrameworkでしかサポートされていないPDFiumViewer
が動かない。Unable to load DLL pdfium.dll
というエラーが出る。.NET Frameworkでビルドした時はこのエラーが出なかったので、.NET6固有の問題のように思う。
PDFをダイレクト印刷したいがためにこれを使っている(それ以外の用途はない)が、PDFがインストールされているマシンなら、プロセスを起動して印刷できるっぽい。
あっさり以下のコード出てきたけど、acrobat32.exe を直で叩いているためか、Acrobat Readerが立ち上がってしまう。また、このやり方はPDFを開くデフォルトアプリケーションがAdobe Readerでないとだめっぽい。Edgeがデフォルトの場合、PrintToオプションがなさそう。
string dir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); //これはいらんかも Process p = new Process(); p.StartInfo = new ProcessStartInfo() { Arguments = "\"" + printer+ "\"", Verb = "PrintTo", FileName = path, //put the correct path here WorkingDirectory = dir, WindowStyle = ProcessWindowStyle.Hidden }; p.Start(); p.WaitForExit(1500);
なんて思ってたら、RawPrint
なるものがあった!
Parallelsの仮想プリンタは印刷できず、Windowsの仮想PDFプリンタは印刷が実行された。なんだろう。コードすげー少ない。とりまfork。実機のプリンタで印刷できれば、なんでもええわ。
10年前に印刷要件の関係でWPFを選んだけど、全部Reactで焼き直したい気持ちが極めて強い... 1年ぐらいかけてまったりと。PDFのダイレクト印刷がReactでできれば、複合機・ドットインパクトプリンタはあまり変わらないはず? ページサイズの設定などが出来ないとやっぱWPFじゃんになるかもですが。
数値をバインドしてるTextBoxの入力値が空になるとエラーになる
現象の説明はこちらに詳しい。
Decimal?
とかでnull許容型にしているデータをTextBoxへバインドすると、入力値を消して空にしたときに、赤枠でエラーが出る。何か入力したあとにバックスペースで空文字にすると、空文字として扱われてしまうため、NULLに変換できないためにそのようなことが起こる。
tawamuredays.blog.fc2.com
上記の記事ではConveter作っていたけど、実はBindingにそのようなためのプロパティがある。TargetNullValue
だ。
blog.okazuki.jp
<TextBox Text="{Binding Path=NumberInput, UpdateSourceTrigger=PropertyChanged, TargetNullValue=''}" />
これで空文字のときはnullと同等の扱いとなる。めでたしめでたし。
PlanetScale、大変興味があります
HerokuのMySQL AddonはRDSを$10から使えるのでその意味でコスパが良いけど、1時間に投げられるクエリの数に制限があり、一番安いプランはHDDで海外リージョン。今の所これが最もコスパが良い選択肢ではあった。ホストOSを管理しないで、LB/App/DBの3層が用意できるから。
GMOが運営しているConohaのDBサーバは$5でSSDで国内にあるが、ユーザー同時接続数(max_user_connections=5
)に制限があり、あまりヘビーには使えない。ただ、SQLAlchemy上で20のコネクションプールを貼ってるが全然当該エラーが起きないので、静観してる。でも、LB/Appのフロント部分は自分で頑張るしかない。実質オンプレミス。
RDS/Auroraはこれらのサービスに比べるとガツンと値段があがる。スケールするサービスを作るには最高なんだろうが、「年間数万レコード/同接多くて30」という業務システムのDBインフラとして「牛刀をもって鶏を割く」感が強く、数千円でホストOSの管理を一切しないで回せるインフラあるといいな〜ってずっと思ってた。そこで、PlanetScaleが出てきて、国内リージョンがあるので、お?って思ったわけ。
DBはPlanetScaleだとして、Vercel/Render/Cloud Runあたりが候補になるのかな、フロントは。Cloud Runが国内だし、PlanetScale + Cloud Runでいいかもしれない。