GQlalchemyを用いたロバストアプリケーションの構築


Webアプリケーション全体を構築するには、必要なデータをデータベースに保存し、必要に応じてロードします.データを取得するのはエラーが発生する可能性がありますので、1つのマイナーなtypoがバグを引き起こす可能性があります.このチュートリアルでは、Twitch analytics app GQlalchemy、オブジェクトグラフマッパー(OGM)の助けを借りて、グラフベースのアプリケーションを構築するはるかに簡単です.

バックエンド実装
このチュートリアルでは、Twitchデータセットから最も人気のあるゲームを見つけるつもりです.The dataTwitch API , このチュートリアルでは、streamers.csv ファイル.まず、必要なデータクラスを models.py :
from gqlalchemy import Node, Field, Relationship
from typing import Optional
from app import memgraph
class User(Node):
    name: str = Field(index=True, exists=True, unique=True, db=memgraph)
class Stream(User):
    name: Optional[str] = Field(
        index=True, exists=True, unique=True, db=memgraph, label="User"
    )
    id: str = Field(index=True, exists=True, unique=True, db=memgraph)
    url: Optional[str] = Field()
    followers: Optional[int] = Field()
    createdAt: Optional[str] = Field()
    totalViewCount: Optional[int] = Field()
    description: Optional[str] = Field()
class Game(Node):
    name: str = Field(unique=True, db=memgraph)
次に、CSVファイルからデータを読み込みます.
def load_streams(path):
    with open(path) as read_obj:
        csv_reader = reader(read_obj)
        header = next(csv_reader)
        if header != None:
            for row in csv_reader:
                stream = models.Stream(
                    id=row[1],
                    name=row[3],
                    url=row[6],
                    followers=row[7],
                    createdAt=row[10],
                    totalViewCount=row[9],
                    description=row[8],
                ).save(memgraph)
                game = models.Game(name=row[4]).save(memgraph)
                plays_rel = models.Plays(
                    _start_node_id=stream._id, _end_node_id=game._id
                ).save(memgraph)
GQLAlchemyのオブジェクトグラフマッパー(OGM)を使用してオブジェクトをモデル化しました.これはスキーマ検証を提供しますので、MemGraphの内部のデータが正確であることを確認できます.
すべての読み込み方法は twitch_data.py .
データがロードされた後、 app.py 最も人気のあるゲームを見つけるには:
@app.route("/top-games/<num_of_games>", methods=["GET"])
@log_time
def get_top_games(num_of_games):
    """Get top num_of_games games by number of streamers who play them."""
    try:
        results = list(
            Match()
            .node("Stream", variable="s")
            .to("PLAYS")
            .node("Game", variable="g")
            .return_({"g.name": "game_name", "count(s)": "num_of_players"})
            .order_by("num_of_players DESC")
            .limit(num_of_games)
            .execute()
        )
        games_list = list()
        players_list = list()
        for result in results:
            game_name = result["game_name"]
            num_of_players = result["num_of_players"]
            games_list.append(game_name)
            players_list.append(num_of_players)
        games = [{"name": game_name} for game_name in games_list]
        players = [{"players": player_count} for player_count in players_list]
        response = {"games": games, "players": players}
        return Response(
            response=dumps(response), status=200, mimetype="application/json"
        )
    except Exception as e:
        log.info("Fetching top games went wrong.")
        log.info(e)
        return ("", 500)
gqlalchemyからのクエリビルダは、データベースでクエリが実行される前に、エラーが発生した場合にCypherクエリの書き込みを避けるために使用されました.上記のクエリは、どのように多くのストリーマは、各ゲームをプレイし、降順で結果を返します.これは、MemgraphのCypherクエリとして実行されるとき、クエリビルダ構築がどのように見えるかです

  • クエリビルダ
  • Match()
    .node("Stream", variable="s")
    .to("PLAYS")
    .node("Game", variable="g")
    .return_({"g.name": "game_name", "count(s)": "num_of_players"})
    .order_by("num_of_players DESC")
    .limit(num_of_games)
    .execute()
    

  • Cypherクエリ
  • MATCH (s:Stream)-[:PLAYS]->(g:Game)
    RETURN g.name AS game_name, count(s) AS num_of_players
    ORDER BY num_of_players DESC LIMIT num_of_games;
    
    この要求では、取得する方法を多くのトップゲームを決定することができます.フロントエンドで得られるレスポンスはJSONgames and players キーとして.

    フロントエンド実装
    最後に、あなたの結果を視覚化する方法を示しましょう.The frontend セマンティックUIの反応の助けを借りて構築されます.
    バックエンドからデータを取得するコンポーネントを作成する必要があります.最も重要な部分はフェッチです.コンポーネントをマウントした直後にコールする必要がありますcomponentDidMount() メソッド:
    fetchData(number) {
        fetch("/top-games/" + number)
            .then((res) => res.json())
            .then(
            (result) => {
                this.setState({
                    isLoaded: true,
                    games: result.games,
                    players: result.players,
                });
            },
            (error) => {
                this.setState({
                    isLoaded: true,
                    error,
                });
            }
            );
        this.setState({
            numOfGames: number,
            header: "Top " + number + " games",
        });
    }
    componentDidMount() {
        this.fetchData(this.state.numOfGames);
    }
    
    その後、結果を保存することができますgames and players あなたが望む状態変数.あなたがインスピレーションを必要とするならば、チェックしてください Games.js コンポーネント.


    結論
    Pythonでのノードとリレーションシップを表すクラスを作成すると、データをより多く制御できます.GQLAlchemyを簡単にグラフデータベースを使用すると、すでに精通しているスタックを使用して通信することができます.GQLalchemyのOGMやクエリビルダについての質問がある場合はDiscord サーバーと私たちにメッセージをドロップします.また、あなたが来るすべてのプロジェクトを共有することができます!