🎃

firestoreのpython orm、fireoで簡単にfirestoreを使う ②モデルとデータの保存

2023/02/27に公開

結構なボリュームになりそうなので分けて書いていきます。
①はじめに 簡単な使い方 
②モデルの定義方法と保存方法 (こちらの記事となります。)

こちらの記事はドキュメントより必要な点を抜粋しています。

モデルについて

FireOは最初にモデル(データのひな型)を作ります。
基本はfrom fireo.model import Modelを行い、Modelを継承して作成していきます。
以下のようにしてモデルを定義します。

class MyModel(Model):
    uid = IDField()
    user_name = TextField(required=True)

作成できるフィールドはIDField() , TextField() , NumberField() , BooleanField , ListField() , MapField(), DateTime() , GeoPoint() があります。

それぞれに必要なattributeを設定できますが、共通のattributeとしてdefault , required , column_name , validator が利用できます。

default

default="defaultvalue"とすることでデフォルト値を割り振ることができます。

required

required=Trueとすることでsave時に必須とできます。

column_name

column_name="nameyoulike"
通常はモデル作成時に付けた名がそのまま割り振られますが、別の名称を割り振りたいときに使います。

validator

validator=myvalidator
とすることで、バリデータを設定できます。バリデータはbooleanを返す必要があります。

それぞれのFieldの説明

各Fieldには上記の共通Attributeのほか、それぞれカスタム属性があり、柔軟にモデルを定義することができます。

ID Field

一意のIDが作成されます。

Text Field

文字列のフィールドです。共通attributeに加え、以下のattributeで初期化できます。

  • max_length
    最大文字数を定義できます。それ以上の文字数を入れた場合はその文字数までトリミングされます。

  • to_lowercase
    to_lowercase=Trueとすることですべて小文字にできます。

  • format
    format="title | upper | lower | capitalize" で文字列を決まったフォーマットに変換します。

Number Field

数字を扱うフィールドです。共通attributeに加え、以下のattributeで初期化できます。

  • int_only
    int_only=Trueとすることで整数のみ扱えるようにできます。

  • float_only
    float_only=Trueとすることで小数のみ扱えるようにできます。

  • range
    range=(start,stop)とすることで指定した値の間の数字のみ入るようにできます。
    Noneを指定することで上限・下限をなくすこともできます。

Boolean Field

真偽値を扱うフィールドです。共通attributeが使用できます。

List Field

リストを扱うフィールドです。共通attributeに加え、作成したモデルを使用することもできます。使用法は以下となります。

example usage
class User(Model):
  subjects = ListField(TextField())  
  
u = User()
u.subjects = ['English', 'Math']

example usage with nestedField
class Message(Model):
    author = TextField()
    text = TextField()
  
class Chat(Model):
    title = TextField()
    messages = ListField(NestedModelField(Message))
  
Chat.from_dict({
    'title': 'Chat 1',
    'messages': [
        {
            'author': 'John',
            'text': 'Hello',
        },
        {
            'author': 'Jane',
            'text': 'Hi',
        }
    ]
}
Map Field

Mapを扱うフィールドです。以下がサンプルとなります。

class User(Model):
    marks = MapField()


u = User()
u.marks = {'Math': 70, 'English': 80}

DateTime

日時を扱うフィールドです。 共通attributeに加え、以下のattributeが使用できます。

  • auto
    auto=Trueとすることでインスタンス化した日時を自動的に挿入します。
GeoPoint

緯度・経度を扱うフィールドです。以下のように利用します。

geopoint sample usage
class User(Model):
    location = GeoPoint()


u = User()
u.location = fireo.GeoPoint(latitude=123.23, longitude=421.12)

Reference Field

FirestoreでいうところのDocumentReferenceを表すフィールドとなります。
他のFieldは文字列や数字といったプリミティブな属性でしたが、こちらはDocumentReferenceそのものを表すフィールドとなります。存在する、しないに関わらず表すことになりますので扱いには注意が必要だと思いますが、非常に使いやすいと思います。

example usage
class Company(Model):
    name = TextField()


class Employee(Model):
    name = TextField()
    company = ReferenceField(Company)

c = Company(name="Abc_company")
c.save()

e = Employee()
e.name = 'Employee Name'
e.company = c
e.save()


共通attributeに加え、以下のattributeが利用できます。

  • auto_load
    通常はTrueとなっています。自動的にDocumentReferenceを取得します。
example usage
class Employee(Model):
    name = TextField()
    company = ReferenceField(Company, auto_load=False)


e = Employee.collection.get(emp_key)
print(e.company)  # object of ReferenceDocLoader

# Reference document can be get using get() method
com = e.company.get()
print(com.name)

  • on_load
    ロード時に指定の関数を実行することができます。
example usage
class Employee(Model):
    name = TextField()
    company = ReferenceField(Company, on_load=do_something)

    def do_something(self, company):
        # do something with company document
        print(company.name)

モデルの保存・読み込み

作成したモデルはFirestoreに保存・読み込みを行うことができます。
Userというモデルを作成したとして、以下のように保存できます。

保存と消去

保存

save sample

from fireo import models as mdl


class User(mdl.Model):
    name = mdl.TextField()
    age = mdl.NumberField()

u = User()
u.name = "Azeem"
u.age = 26
u.save()

コンストラクタを利用することもできます。

sample usage 2
u = User(name="Azeem", age=26)
u.save()

ディクショナリからオブジェクトを作成することもできます。

sample usage 3
model_dict = {'name': 'Azeem', 'age': 26}
u = User.from_dict(model_dict)
u.save()

また、upsert()もしくはsave(merge=True)メソッドを利用することで同じオブジェクトが保存されている場合は上書きすることができます。

upsert sample
u = User()
u.id = "custom-id"
u.name = "Azeem"
u.save(merge=True)
# OR
u.upsert()

消去

keyを利用します。keyはクエリを使って取得するほか、作成したモデルのkeyでもあります。

sample usage
User.collection.delte(user_key)

Discussion