ETLãã€ãã©ã€ã³ã«ãããåå®å šãªããŒã¿å€æãæ¢æ±ãéçåä»ãã«ãããå ç¢ã§ä¿¡é Œæ§ãé«ããä¿å®ããããããŒã¿ã¯ãŒã¯ãããŒãå®è£ ããããŒã¿å質ãåäžããããšã©ãŒãåæžããæ¹æ³ãåŠã³ãŸãã
åå®å šãªããŒã¿å€æïŒETLãã€ãã©ã€ã³ã®ç²Ÿå¯ãªå®è£
çµ¶ããé²åããããŒã¿ãšã³ãžãã¢ãªã³ã°ã®åéã«ãããŠãExtract, Transform, Load (ETL) ãã€ãã©ã€ã³ã¯ãåæãšæææ±ºå®ã®ããã®ããŒã¿ãçµ±åãæºåããäžã§äŸç¶ãšããŠèŠãšãªã£ãŠããŸããããããåŸæ¥ã®ETLã¢ãããŒãã¯ãããŒã¿å質ãã©ã³ã¿ã€ã ãšã©ãŒãä¿å®æ§ã«é¢ããåé¡ã«æ©ãŸãããããšããããããŸããåå®å šãªããŒã¿å€ææè¡ãæ¡çšããããšã¯ããããã®èª²é¡ã«å¯Ÿãã匷åãªè§£æ±ºçãæäŸããå ç¢ã§ä¿¡é Œæ§ãé«ããã¹ã±ãŒã©ãã«ãªããŒã¿ãã€ãã©ã€ã³ã®æ§ç¯ãå¯èœã«ããŸãã
åå®å šãªããŒã¿å€æãšã¯ïŒ
åå®å šãªããŒã¿å€æã¯ãéçåä»ããæŽ»çšããŠãETLããã»ã¹å šäœã§ããŒã¿ãæåŸ ãããã¹ããŒããšå¶çŽã«æºæ ããŠããããšãä¿èšŒããŸãããã®äºå察å¿çãªã¢ãããŒãã¯ãã³ã³ãã€ã«æãŸãã¯å®è¡ã®åææ®µéã§æœåšçãªãšã©ãŒãææãããã€ãã©ã€ã³ãéããŠäžæµã®ããŒã¿ãç Žæãããã®ãé²ããŸãã
åå®å šãªããŒã¿å€æã®äž»ãªå©ç¹ïŒ
- ããŒã¿å質ã®åäžïŒå倿ã¹ãããã§ããŒã¿åãšæ§é ãæ€èšŒããããšã§ãããŒã¿ã®äžè²«æ§ãšæŽåæ§ã匷å¶ããŸãã
- ã©ã³ã¿ã€ã ãšã©ãŒã®åæžïŒåé¢é£ã®ãšã©ãŒãæ©æã«ææãããã€ãã©ã€ã³å®è¡äžã®äºæãã¬é害ãé²ããŸãã
- ä¿å®æ§ã®åäžïŒã³ãŒãã®æç¢ºæ§ãšå¯èªæ§ãåäžãããETLãã€ãã©ã€ã³ã®çè§£ããããã°ã倿Žã容æã«ããŸãã
- ä¿¡é Œæ§ã®åäžïŒå€æãããããŒã¿ã®æ£ç¢ºæ§ãšä¿¡é Œæ§ã«å¯Ÿãããã倧ããªä¿èšŒãæäŸããŸãã
- ããè¯ãã³ã©ãã¬ãŒã·ã§ã³ïŒæç¢ºãªããŒã¿å¥çŽãæäŸããããšã§ãããŒã¿ãšã³ãžãã¢ãšããŒã¿ãµã€ãšã³ãã£ã¹ãéã®ã³ã©ãã¬ãŒã·ã§ã³ãä¿é²ããŸãã
åå®å šãªETLãã€ãã©ã€ã³ã®å®è£ ïŒäž»èŠãªæŠå¿µ
åå®å šãªETLãã€ãã©ã€ã³ãæ§ç¯ããã«ã¯ãããã€ãã®äž»èŠãªæŠå¿µãšæè¡ãé¢ãããŸãïŒ
1. ã¹ããŒãå®çŸ©ãšæ€èšŒ
åå®å šãªETLã®åºç€ã¯ãããŒã¿ã«æç€ºçãªã¹ããŒããå®çŸ©ããããšã«ãããŸããã¹ããŒãã¯ãååãããŒã¿åïŒäŸïŒæŽæ°ãæååãæ¥ä»ïŒãå¶çŽïŒäŸïŒnulläžå¯ãäžæïŒãªã©ãããŒã¿ã®æ§é ãšããŒã¿åãèšè¿°ããŸããApache AvroãProtocol Buffersããããã¯èšèªåºæã®ã©ã€ãã©ãªïŒScalaã®ã±ãŒã¹ã¯ã©ã¹ãPythonã®Pydanticãªã©ïŒã®ãããªã¹ããŒãå®çŸ©ããŒã«ã䜿çšããããšã§ãããŒã¿ã®æ§é ãæ£åŒã«å®£èšã§ããŸãã
äŸïŒ
顧客ããŒã¿ããŒã¹ããããŒã¿ãæœåºããŠãããšããŸããããCustomerããŒã¿ã®ã¹ããŒãã¯æ¬¡ã®ããã«å®çŸ©ã§ããŸãïŒ
{
"type": "record",
"name": "Customer",
"fields": [
{"name": "customer_id", "type": "int"},
{"name": "first_name", "type": "string"},
{"name": "last_name", "type": "string"},
{"name": "email", "type": "string"},
{"name": "registration_date", "type": "string"} // ISO 8601圢åŒãæ³å®
]
}
倿ãè¡ãåã«ããã®ã¹ããŒãã«å¯ŸããŠåä¿¡ããŒã¿ãæ€èšŒããå¿ èŠããããŸããããã«ãããããŒã¿ãæåŸ ãããæ§é ãšããŒã¿åã«æºæ ããŠããããšãä¿èšŒãããŸããã¹ããŒãã«éåããããŒã¿ã¯æåŠãããããé©åã«åŠçãããã¹ãã§ãïŒäŸïŒèª¿æ»ã®ããã«ãã°ã«èšé²ããïŒã
2. éçåä»ããšããŒã¿å¥çŽ
ScalaãJavaãªã©ã®èšèªã§æäŸãããMyPyã®ãããªããŒã«ã§Pythonã§ãæ¡çšãå¢ããŠããéçåä»ãã¯ãåå®å šæ§ã匷å¶ããäžã§éèŠãªåœ¹å²ãæãããŸããéçåã䜿çšããããšã§ãå倿ã¹ãããã®æåŸ ãããå ¥åããã³åºååãæå®ããããŒã¿å¥çŽãå®çŸ©ã§ããŸãã
äŸïŒScalaïŒïŒ
case class Customer(customerId: Int, firstName: String, lastName: String, email: String, registrationDate: String)
def validateEmail(customer: Customer): Option[Customer] = {
if (customer.email.contains("@") && customer.email.contains(".")) {
Some(customer)
} else {
None // ç¡å¹ãªã¡ãŒã«ã¢ãã¬ã¹
}
}
ãã®äŸã§ã¯ãvalidateEmail颿°ã¯ãCustomerãªããžã§ã¯ããå
¥åãšããŠåãåããæå¹ãªé¡§å®¢ãŸãã¯äœããªãããšã瀺ãOption[Customer]ãè¿ãããšãæç€ºçã«ç€ºããŠããŸããããã«ãããã³ã³ãã€ã©ã¯é¢æ°ãæ£ãã䜿çšãããåºåãé©åã«åŠçãããŠããããšãæ€èšŒã§ããŸãã
3. 颿°åããã°ã©ãã³ã°ã®åå
ã€ãã¥ãŒã¿ãã«æ§ãçŽç²é¢æ°ãå¯äœçšã®åé¿ãšãã£ã颿°åããã°ã©ãã³ã°ã®ååã¯ãåå®å šãªããŒã¿å€æã«ç¹ã«é©ããŠããŸããã€ãã¥ãŒã¿ãã«ãªããŒã¿æ§é ã¯ãããŒã¿ããã®å Žã§å€æŽãããªãããšãä¿èšŒããäºæãã¬å¯äœçšãé²ãã倿ããã»ã¹ã«ã€ããŠæšè«ããããããŸããåãå ¥åã«å¯ŸããŠåžžã«åãåºåãè¿ããå¯äœçšã®ãªãçŽç²é¢æ°ã¯ãäºæž¬å¯èœæ§ãšãã¹ãå®¹ææ§ãããã«åäžãããŸãã
äŸïŒé¢æ°åããã°ã©ãã³ã°ã䜿çšããPythonïŒïŒ
from typing import NamedTuple, Optional
class Customer(NamedTuple):
customer_id: int
first_name: str
last_name: str
email: str
registration_date: str
def validate_email(customer: Customer) -> Optional[Customer]:
if "@" in customer.email and "." in customer.email:
return customer
else:
return None
ããã§ã`Customer`ã¯ã€ãã¥ãŒã¿ãã«ãªããŒã¿æ§é ã衚ãååä»ãã¿ãã«ã§ãã`validate_email`颿°ãçŽç²é¢æ°ã§ããã`Customer`ãªããžã§ã¯ããåãåããã¡ãŒã«æ€èšŒã«åºã¥ããŠãªãã·ã§ã³ã®`Customer`ãªããžã§ã¯ããè¿ããŸãããã®éãå ã®`Customer`ãªããžã§ã¯ãã倿Žããããä»ã®å¯äœçšãåŒãèµ·ããããããããšã¯ãããŸããã
4. ããŒã¿å€æã©ã€ãã©ãªãšãã¬ãŒã ã¯ãŒã¯
åå®å šãªããŒã¿å€æã容æã«ããã©ã€ãã©ãªããã¬ãŒã ã¯ãŒã¯ãããã€ããããŸãããããã®ããŒã«ã¯ãã¹ããŒãå®çŸ©ãããŒã¿æ€èšŒãçµã¿èŸŒã¿ã®åãã§ãã¯ãåãã倿颿°ãªã©ã®æ©èœãæäŸããããšããããããŸãã
- Apache Spark ãš ScalaïŒSpark 㯠Scala ã®åŒ·åãªåä»ãã·ã¹ãã ãšçµã¿åãããããšã§ãåå®å šãª ETL ãã€ãã©ã€ã³ãæ§ç¯ããããã®åŒ·åãªãã©ãããã©ãŒã ãæäŸããŸããSpark ã® Dataset API ã¯ãããŒã¿å€æã®ããã®ã³ã³ãã€ã«æåå®å šæ§ãæäŸããŸãã
- Apache BeamïŒBeam ã¯ãããããã³ã¹ããªãŒãã³ã°ããŒã¿åŠçã®äž¡æ¹ã«å¯Ÿå¿ããçµ±åããã°ã©ãã³ã°ã¢ãã«ãæäŸããæ§ã ãªå®è¡ãšã³ãžã³ïŒSparkãFlinkãGoogle Cloud Dataflowãªã©ïŒããµããŒãããŸããBeam ã®åã·ã¹ãã ã¯ãç°ãªãåŠçã¹ããŒãžéã§ã®ããŒã¿ã®äžè²«æ§ã確ä¿ããã®ã«åœ¹ç«ã¡ãŸãã
- dbt (Data Build Tool)ïŒdbt ã¯ããã°ã©ãã³ã°èšèªèªäœã§ã¯ãããŸããããSQL ãš Jinja ã䜿çšããŠããŒã¿ãŠã§ã¢ããŠã¹å ã®ããŒã¿ã倿ããããã®ãã¬ãŒã ã¯ãŒã¯ãæäŸããŸããããè€éãªå€æãšããŒã¿æ€èšŒã®ããã«ãåå®å šãªèšèªãšçµ±åããããšãã§ããŸãã
- Pydantic ãš MyPy ã䜿çšãã PythonïŒPydantic 㯠Python ã®åã¢ãããŒã·ã§ã³ã䜿çšããŠããŒã¿æ€èšŒãšèšå®ç®¡çãå®çŸ©ã§ããŸããMyPy 㯠Python ã³ãŒãã®éçåãã§ãã¯ãæäŸããã©ã³ã¿ã€ã åã«åé¢é£ã®ãšã©ãŒãæ€åºããããšãå¯èœã«ããŸãã
åå®å šãªETLå®è£ ã®å®è·µäŸ
ç°ãªãæè¡ã䜿çšããŠåå®å šãªETLãã€ãã©ã€ã³ãå®è£ ããæ¹æ³ã説æããŸãããã
äŸ1ïŒApache SparkãšScalaã«ããåå®å šãªETL
ãã®äŸã§ã¯ãCSVãã¡ã€ã«ãã顧客ããŒã¿ãèªã¿èŸŒã¿ãäºåå®çŸ©ãããã¹ããŒãã«å¯ŸããŠããŒã¿ãæ€èšŒããParquetãã¡ã€ã«ã«ããŒã¿ã倿ããã·ã³ãã«ãªETLãã€ãã©ã€ã³ã瀺ããŸããããã¯ãã³ã³ãã€ã«æåå®å šæ§ã®ããã«Sparkã®Dataset APIãå©çšããŠããŸãã
import org.apache.spark.sql.{Dataset, SparkSession}
import org.apache.spark.sql.types._
import org.apache.spark.sql.functions._
case class Customer(customerId: Int, firstName: String, lastName: String, email: String, registrationDate: String)
object TypeSafeETL {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder().appName("TypeSafeETL").master("local[*]").getOrCreate()
import spark.implicits._
// ã¹ããŒãã®å®çŸ©
val schema = StructType(Array(
StructField("customerId", IntegerType, nullable = false),
StructField("firstName", StringType, nullable = false),
StructField("lastName", StringType, nullable = false),
StructField("email", StringType, nullable = false),
StructField("registrationDate", StringType, nullable = false)
))
// CSVãã¡ã€ã«ã®èªã¿èŸŒã¿
val df = spark.read
.option("header", true)
.schema(schema)
.csv("data/customers.csv")
// Dataset[Customer]ãžã®å€æ
val customerDS: Dataset[Customer] = df.as[Customer]
// 倿ïŒã¡ãŒã«ã¢ãã¬ã¹ã®æ€èšŒ
val validCustomers = customerDS.filter(customer => customer.email.contains("@") && customer.email.contains("."))
// ããŒãïŒParquetãžã®æžã蟌ã¿
validCustomers.write.parquet("data/valid_customers.parquet")
spark.stop()
}
}
説æïŒ
- ã³ãŒãã¯ããŒã¿æ§é ã衚ã
Customerã±ãŒã¹ã¯ã©ã¹ãå®çŸ©ããŸãã - äºåå®çŸ©ãããã¹ããŒããæã€CSVãã¡ã€ã«ãèªã¿èŸŒã¿ãŸãã
- DataFrameãã³ã³ãã€ã«æåå®å
šæ§ãæäŸãã
Dataset[Customer]ã«å€æããŸãã - æå¹ãªã¡ãŒã«ã¢ãã¬ã¹ãæã€é¡§å®¢ã®ã¿ãå«ãããã«ããŒã¿ããã£ã«ã¿ãªã³ã°ããŸãã
- 倿ãããããŒã¿ãParquetãã¡ã€ã«ã«æžã蟌ã¿ãŸãã
äŸ2ïŒPythonãPydanticãMyPyã«ããåå®å šãªETL
ãã®äŸã§ã¯ãPydanticãããŒã¿æ€èšŒã«ãMyPyãéçåãã§ãã¯ã«äœ¿çšããŠãPythonã§åå®å šæ§ãå®çŸããæ¹æ³ã瀺ããŸãã
from typing import List, Optional
from pydantic import BaseModel, validator
class Customer(BaseModel):
customer_id: int
first_name: str
last_name: str
email: str
registration_date: str
@validator("email")
def email_must_contain_at_and_dot(cls, email: str) -> str:
if "@" not in email or "." not in email:
raise ValueError("Invalid email format")
return email
def load_data(file_path: str) -> List[dict]:
# ãã¡ã€ã«ããã®ããŒã¿èªã¿èŸŒã¿ãã·ãã¥ã¬ãŒãïŒå®éã®ãã¡ã€ã«èªã¿èŸŒã¿ã«çœ®ãæããïŒ
return [
{"customer_id": 1, "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "registration_date": "2023-01-01"},
{"customer_id": 2, "first_name": "Jane", "last_name": "Smith", "email": "jane.smith@example.net", "registration_date": "2023-02-15"},
{"customer_id": 3, "first_name": "Peter", "last_name": "Jones", "email": "peter.jonesexample.com", "registration_date": "2023-03-20"},
]
def transform_data(data: List[dict]) -> List[Customer]:
customers: List[Customer] = []
for row in data:
try:
customer = Customer(**row)
customers.append(customer)
except ValueError as e:
print(f"Error validating row: {row} - {e}")
return customers
def save_data(customers: List[Customer], file_path: str) -> None:
# ãã¡ã€ã«ãžã®ããŒã¿ä¿åãã·ãã¥ã¬ãŒãïŒå®éã®ãã¡ã€ã«æžã蟌ã¿ã«çœ®ãæããïŒ
print(f"Saving {len(customers)} valid customers to {file_path}")
for customer in customers:
print(customer.json())
if __name__ == "__main__":
data = load_data("data/customers.json")
valid_customers = transform_data(data)
save_data(valid_customers, "data/valid_customers.json")
説æïŒ
- ã³ãŒãã¯Pydanticã®
BaseModelã䜿çšããŠCustomerã¢ãã«ãå®çŸ©ããŸãããã®ã¢ãã«ã¯ããŒã¿ã«åå¶çŽã匷å¶ããŸãã - ããªããŒã¿ãŒé¢æ°ã¯ãã¡ãŒã«ãã£ãŒã«ãã«ã@ããšã.ãã®äž¡æ¹ãå«ãŸããŠããããšã確èªããããã«äœ¿çšãããŸãã
transform_data颿°ã¯ãå ¥åããŒã¿ããCustomerãªããžã§ã¯ããäœæããããšããŸããããŒã¿ãã¹ããŒãã«æºæ ããªãå ŽåãValueErrorãã¹ããŒãããŸãã- MyPyã¯ã³ãŒããéçã«åãã§ãã¯ããã©ã³ã¿ã€ã åã«æœåšçãªåãšã©ãŒãææããããã«äœ¿çšã§ããŸãããã¡ã€ã«ã確èªããã«ã¯`mypy your_script.py`ãå®è¡ããŸãã
åå®å šãªETLãã€ãã©ã€ã³ã®ããã®ãã¹ããã©ã¯ãã£ã¹
åå®å šãªããŒã¿å€æã®å©ç¹ãæå€§éã«åŒãåºãããã«ã以äžã®ãã¹ããã©ã¯ãã£ã¹ãèæ ®ããŠãã ããïŒ
- æ©æã®ã¹ããŒãå®çŸ©ïŒããŒã¿ãœãŒã¹ãšã¿ãŒã²ããã«å¯Ÿããæç¢ºã§å æ¬çãªã¹ããŒãã®å®çŸ©ã«æéãæè³ããŸãã
- ããããæ®µéã§ã®ããŒã¿æ€èšŒïŒãšã©ãŒãæ©æã«ææããããã«ãå倿ã¹ãããã§ããŒã¿æ€èšŒãã§ãã¯ãå®è£ ããŸãã
- é©åãªããŒã¿åã䜿çšããïŒããŒã¿ãæ£ç¢ºã«è¡šçŸããå¿ èŠã«å¿ããŠå¶çŽã匷å¶ããããŒã¿åãéžæããŸãã
- 颿°åããã°ã©ãã³ã°ã®æ¡çšïŒäºæž¬å¯èœã§ãã¹ãå¯èœãªå€æãäœæããããã«ã颿°åããã°ã©ãã³ã°ã®ååãæŽ»çšããŸãã
- ãã¹ãã®èªååïŒETLãã€ãã©ã€ã³ã®æ£ç¢ºæ§ãä¿èšŒããããã«ãå æ¬çãªåäœãã¹ããšçµåãã¹ããå®è£ ããŸãã
- ããŒã¿å質ã®ç£èŠïŒããŒã¿å質ã¡ããªã¯ã¹ãç¶ç¶çã«ç£èŠããããŒã¿ã®åé¡ãç©æ¥µçã«æ€åºããŠå¯ŸåŠããŸãã
- é©åãªããŒã«ã®éžæïŒåŒ·åãªåå®å šæ§ãšããŒã¿æ€èšŒæ©èœãæäŸããããŒã¿å€æã©ã€ãã©ãªãšãã¬ãŒã ã¯ãŒã¯ãéžæããŸãã
- ãã€ãã©ã€ã³ã®ææžåïŒã¹ããŒãå®çŸ©ã倿ããžãã¯ãããŒã¿å質ãã§ãã¯ãªã©ãETLãã€ãã©ã€ã³ã培åºçã«ææžåããŸããæç¢ºãªææžã¯ä¿å®æ§ãšã³ã©ãã¬ãŒã·ã§ã³ã«ãšã£ãŠäžå¯æ¬ ã§ãã
課é¡ãšèæ ®äºé
åå®å šãªããŒã¿å€æã¯å€ãã®å©ç¹ãæäŸããŸãããããã€ãã®èª²é¡ãšèæ ®äºé ãæç€ºããŸãïŒ
- åŠç¿æ²ç·ïŒåå®å šãªèšèªããã¬ãŒã ã¯ãŒã¯ã®æ¡çšã¯ãããŒã¿ãšã³ãžãã¢ã«ãšã£ãŠåŠç¿æ²ç·ãå¿ èŠãšãªãå ŽåããããŸãã
- éçºå·¥æ°ã®å¢å ïŒåå®å šãªETLãã€ãã©ã€ã³ã®å®è£ ã¯ãåŸæ¥ã®ã¢ãããŒããšæ¯èŒããŠãããå€ãã®åæéçºå·¥æ°ãå¿ èŠãšããå ŽåããããŸãã
- ããã©ãŒãã³ã¹ãªãŒããŒãããïŒããŒã¿æ€èšŒãšåãã§ãã¯ã¯ãããçšåºŠã®ããã©ãŒãã³ã¹ãªãŒããŒããããåŒãèµ·ããå¯èœæ§ããããŸããããããããŒã¿å質ã®åäžãšã©ã³ã¿ã€ã ãšã©ãŒã®åæžãšããå©ç¹ã¯ãå€ãã®å Žåãã®ã³ã¹ããäžåããŸãã
- ã¬ã¬ã·ãŒã·ã¹ãã ãšã®çµ±åïŒåŒ·åãªåä»ãããµããŒãããªãã¬ã¬ã·ãŒã·ã¹ãã ãšåå®å šãªETLãã€ãã©ã€ã³ãçµ±åããããšã¯èª²é¡ãšãªãå ŽåããããŸãã
- ã¹ããŒãé²åïŒã¹ããŒãé²åïŒããªãã¡ãæéã®çµéã«äŒŽãããŒã¿ã¹ããŒãã®å€æŽïŒã®åŠçã«ã¯ãæ éãªèšç»ãšå®è£ ãå¿ èŠã§ãã
çµè«
åå®å šãªããŒã¿å€æã¯ãå ç¢ã§ä¿¡é Œæ§ãé«ããä¿å®å¯èœãªETLãã€ãã©ã€ã³ãæ§ç¯ããããã®åŒ·åãªã¢ãããŒãã§ããéçåä»ããã¹ããŒãæ€èšŒã颿°åããã°ã©ãã³ã°ã®ååãæŽ»çšããããšã§ãããŒã¿å質ãå€§å¹ ã«åäžãããã©ã³ã¿ã€ã ãšã©ãŒãåæžããããŒã¿ãšã³ãžãã¢ãªã³ã°ã¯ãŒã¯ãããŒå šäœã®å¹çãé«ããããšãã§ããŸããããŒã¿éãšè€éããå¢å€§ãç¶ããã«ã€ããŠãããŒã¿é§ååã€ã³ãµã€ãã®æ£ç¢ºæ§ãšä¿¡é Œæ§ã確ä¿ããããã«ãåå®å šãªããŒã¿å€æãæ¡çšããããšããŸããŸãéèŠã«ãªããŸãã
Apache SparkãApache BeamãPydanticã䜿çšããPythonããŸãã¯ãã®ä»ã®ããŒã¿å€æããŒã«ã䜿çšããŠãããã©ããã«ããããããåå®å šãªãã©ã¯ãã£ã¹ãETLãã€ãã©ã€ã³ã«çµã¿èŸŒãããšã§ãããå埩åããã䟡å€ã®ããããŒã¿ã€ã³ãã©ã¹ãã©ã¯ãã£ã«ã€ãªãããŸããåå®å šãªããŒã¿å€æãžã®éã®ããå§ããããŒã¿åŠçã®å質ãé«ããããã«ãããã§æŠèª¬ãããŠããäŸãšãã¹ããã©ã¯ãã£ã¹ãèæ ®ããŠãã ããã