Life is Really Short, Have Your Life!!

ござ先輩の主に技術的なメモ

SQLAlchemy2.0スタイルメモ〜scalars〜

FastAPIならasyncで全部行きたいねってことで、プロダクトのコードをFlask→FastAPIに書き直している。

で、簡単なクエリの動作確認で、こんなコードを書く。

async def get_posts(db: AsyncSession) -> List[Post]:
    result: Result = await db.execute(select(Post).order_by(Post.postdate.desc()).limit(20))
    return result.all()

この時、JSONになった文字列を見ると、こういう感じで返ってくる。

{ "Post": 
    {
        "id": 1,
        "title": "aaa",
    }
}

なんだこのPostとかいうエンティティ名は。そんなのいらん。何だこれって思って公式見たら、こうやって書くらしい。

async def get_posts(db: AsyncSession) -> List[Post]:
    result: Result = await db.execute(select(Post).order_by(Post.postdate.desc()).limit(20))
    return result.scalars().all()

こうすると、JSONにした時にエンティティ名のPostが外されて、{"id":1,"title":"aaa"}になった。select関数の中で、配列でカラム名を指定する場合にscalarsを使うと、選んだカラムの1つしか返ってこない。まぁ、スカラー値だもんな。オブジェクトの場合はオブジェクトが返り、Selectした場合は最初の値が返ってくる・・・ってなんだこれ。でも、Alchemy使う以上は従うしか無いし。TypeScriptオンリーに早くなりたい。

EPSON VP-4300で「EJL 1284.4@EJL」という文字列が常に印字される

USBでドットインパクトプリンタとWindowsマシンがつながっている状態で、プリンタの共有をかけた。この共有プリンタをインストールしたクライアント側で、必ず EJL1284〜 とかいう文字列が出るようになってしまった。

ぐぐってみたら先駆者がいた。 okwave.jp

以下のような設定画面になるので、パケット通信設定をオフにしたら、この文字列は出なくなった。この文字列はプリンタ制御コードで、何のエラーかわからんが、通信時に発生し、その内容を人間様に教えるために印字されていたようだ。

EPSON的には仮想USBポートでプリンタ共有かけるのではなく、ローカルポートで ¥¥HogePrintServer¥EPSON-ESCPとかやるのが推奨手順らしい。

以下、マニュアル。 https://www2.epson.jp/support/manual/data/dot/vp1900/BPS0141_00_JA.PDF

OKIのMICROLINEで同じ設定をした時は、このような現象は発生しなかった。や沖1。

FlutterでUnixTimeをDateTimeに変換する

Firebaseのライブラリが国際化対応しているため、日時をUnixtimeで持っていた。 それをDartでDateTimeに変換するときのコードで、癖があったのでメモ。

www.kindacode.com

 final timestamp1 = 1627510285; // timestamp in seconds
 final DateTime date1 = DateTime.fromMillisecondsSinceEpoch(timestamp1 * 1000);

fromMillisecondsSinceEpoch はミリ秒を期待しているが、unixtimeが秒までの時間しか持っていないので、1000倍しないとミリ秒が計算されず復元できないというだけの話。

'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で

nextjs.org

以下の所を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

gist.github.com

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的な機能があれば、本件はすぐ解決するのに。

docs.microsoft.com

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月頃かな。頼むぞ。