Metadata-Version: 2.1
Name: fastapi-efficient-sql
Version: 0.0.4
Summary: Generate bulk DML SQL and execute them based on tortoise-orm and mysql8.0+, and integrated with fastapi.
Home-page: https://github.com/NightMarcher/fastapi-efficient-sql
Author: BryanLee
Author-email: bryanlee@126.com
License: MIT
Description: # fastapi-efficient-sql
        
        Installed by `pip install fastapi-efficient-sql`
        
        ## Some preparations before using efficient sql
        ```python
        from fastapi_esql import AppMetaclass, BaseManager, BaseModel
        
        
        class DemoMetaclass(AppMetaclass):
        
            def get_ro_conn(self):
                return Tortoise.get_connection("demo_ro")
        
            def get_rw_conn(self):
                return Tortoise.get_connection("demo_rw")
        
        
        class Account(BaseModel):
            id = fields.IntField(pk=True)
            active = fields.BooleanField(null=False, default=True)
            gender = fields.IntEnumField(GenderEnum, null=False, default=GenderEnum.unknown)
            name = fields.CharField(max_length=32, null=False, default="")
            locale = fields.CharEnumField(LocaleEnum, max_length=5, null=False)
        
        
        class AccountMgr(BaseManager, metaclass=DemoMetaclass):
            model = Account
        ```
        
        ## Some supported efficient sql
        ### **select_custom_fields**
        **basic example**
        ```python
        aids = [1, 2, 3]
        
        await AccountMgr.select_custom_fields(
            fields=[
                "id", "extend ->> '$.last_login.ipv4' ipv4",
                "extend ->> '$.last_login.start_datetime' start_datetime",
                "CAST(extend ->> '$.last_login.online_sec' AS SIGNED) online_sec"
            ],
            wheres=f"id IN ({','.join(map(str, aids))}) AND gender=1",  # These 4 types of `wheres` are equal
            # wheres=Q(Q(id__in=aids), Q(gender=1), join_type="AND"),
            # wheres={"id__in": aids, "gender": 1},
            # wheres=[Q(id__in=aids), Q(gender=1)],
        )
        ```
        Generate sql and execute
        ```sql
            SELECT
                id, extend ->> '$.last_login.ipv4' ipv4, extend ->> '$.last_login.start_datetime' start_datetime, CAST(extend ->> '$.last_login.online_sec' AS SIGNED) online_sec
            FROM account
            WHERE id IN (1,2,3) AND gender=1
        ```
        
        **complex example**
        ```python
        await AccountMgr.select_custom_fields(
            fields=[
                "locale", "gender", "COUNT(1) cnt"
            ],
            wheres=Q(id__range=[1, 12]),
            groups=["locale", "gender"],
            having="cnt > 0",
            orders=["locale", "-gender"],
            limit=10,
        )
        ```
        Generate sql and execute
        ```sql
            SELECT
                locale, gender, COUNT(1) cnt
            FROM account
            WHERE `id` BETWEEN 1 AND 12
            GROUP BY locale, gender
            HAVING cnt > 0
            ORDER BY locale ASC, gender DESC
            LIMIT 10
        ```
        
        ### **update_json_field**
        ```python
        await AccountMgr.update_json_field(
            json_field="extend",
            wheres=Q(id=8),
            merge_dict={
                "updated_at": "2022-10-30 21:34:15",
                "info": {
                    "online_sec": 636,
                }
            },
            path_value_dict={
                "$.last_login": {
                    "ipv4": "209.182.101.161",
                },
                "$.uuid": "fd04f7f2-24fc-4a73-a1d7-b6e99a464c5f",
            },
            remove_paths=["$.deprecated"],
            json_type=dict,
        )
        ```
        Generate sql and execute
        ```sql
            UPDATE account SET extend =
            JSON_MERGE_PATCH(JSON_SET(JSON_REMOVE(COALESCE(extend, '{}'), '$.deprecated'), '$.last_login',CAST('{"ipv4": "209.182.101.161"}' AS JSON), '$.uuid','fd04f7f2-24fc-4a73-a1d7-b6e99a464c5f'), '{"updated_at": "2022-10-30 21:34:15", "info": {"online_sec": 636}}')
            WHERE `id`=8
        ```
        
        ### **upsert_on_duplicate**
        ```python
        await AccountMgr.upsert_on_duplicate(
            [
                {'id': 7, 'gender': 1, 'name': '斉藤 修平', 'locale': 'ja_JP', 'extend': {}},
                {'id': 8, 'gender': 1, 'name': 'Ojas Salvi', 'locale': 'en_IN', 'extend': {}},
                {'id': 9, 'gender': 1, 'name': '羊淑兰', 'locale': 'zh_CN', 'extend': {}}
            ],
            insert_fields=["id", "gender", "name", "locale", "extend"],
            upsert_fields=["name", "locale"],
            using_values=False,
        )
        ```
        Generate sql and execute
        ```sql
            INSERT INTO account
                (id, gender, name, locale, extend)
            VALUES
                (7, 1, '斉藤 修平', 'ja_JP', '{}'), (8, 1, 'Ojas Salvi', 'en_IN', '{}'), (9, 1, '羊淑兰', 'zh_CN', '{}')
            AS `new_account` ON DUPLICATE KEY UPDATE name=`new_account`.name, locale=`new_account`.locale
        ```
        
        ### **insert_into_select**
        ```python
        await AccountMgr.insert_into_select(
            wheres=Q(id__in=[4, 5, 6]),
            remain_fields=["gender"],
            assign_field_dict={
                "locale": Cases("id", {3: LocaleEnum.zh_CN, 4: LocaleEnum.en_US, 5: LocaleEnum.fr_FR}, default=""),
                "active": False,
                "name": RawSQL("CONCAT(LEFT(name, 26), ' [NEW]')"),
                "extend": {},
            },
            to_table="account_bak",
        )
        ```
        Generate sql and execute
        ```sql
            INSERT INTO account_bak
                (gender, locale, active, name, extend)
            SELECT gender, CASE id WHEN 3 THEN 'zh_CN' WHEN 4 THEN 'en_US' WHEN 5 THEN 'fr_FR' ELSE '' END locale, False active, CONCAT(LEFT(name, 26), ' [NEW]') name, '{}' extend
            FROM account
            WHERE `id` IN (4,5,6)
        ```
        
        ### **bulk_update**
        ```python
        await AccountMgr.bulk_update(
            [
                {'id': 7, 'active': False, 'gender': <GenderEnum.male: 1>},
                {'id': 15, 'active': True, 'gender': <GenderEnum.unknown: 0>}
            ],
            join_fields=["id"],
            update_fields=["active", "gender"],
            using_values=True,
        )
        ```
        Generate sql and execute
        ```sql
            UPDATE account
            JOIN (
                SELECT * FROM (
                    VALUES
                    ROW(7, False, 1), ROW(15, True, 0)
                ) AS fly_table (id, active, gender)
            ) tmp ON account.id=tmp.id
            SET account.active=tmp.active, account.gender=tmp.gender
        ```
        
Keywords: sql,fastapi,tortoise-orm,mysql8,bulk-operation
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Description-Content-Type: text/markdown
