Store the ifcJSON in the Database
Store the ifcJSON
This is done by reading the ifcJSON, loading it in pandas DataFrame and or Series and splitting it in categories.
- Representations
- PropertySets
- Relationships
- Objects: all entities that are not in one of the 3 others
Thereafter, there is a basic processing to adjust to the Physical model which is under /src/model/common.py with SQLModel / Pydantic definitions. Hereunder the example of the object table.
class object(SQLModel, table=True):
bundle_id: int = Field(nullable=False, alias='bundleId', primary_key=True)
object_id: UUID4 = Field(primary_key=True)
type: str = Field(nullable=False)
name: str = Field(nullable=True) # have object with no name (e.g. IfcOpeningElement)
representation_ids: list[str] = Field(sa_column=Column(ARRAY(String(36))), default=[], alias='representationIds')
elementjson: dict = Field(sa_column=Column(JSON), default={}, alias='elementJson')
created_at: datetime.datetime = Field(sa_column=Column(DateTime(), default=func.now(), nullable=False))
updated_at: Optional[datetime.datetime] = Field(sa_column=Column(DateTime(), nullable=True ))
- The object_id is the IFC globalId in expanded format as provided by IFC2JSON.
- The type is the IfcEntity Name (IfcProject, IfcSite, IfcBuilding, IfcBuildingStorey, ...). It could be replaced by a shorter id (e.g. int).
- The name is the name provided in the IFC. In principle it should bear some meaning, but that is not always the case. In some IFC, it may just not provided.
- The representation_ids (list / array) are the ids of the representations (geometries). They are extracted from the entity json to be available for queries
- The ifcjson is the copy of the entity dictionary provided by ifcJSON. It is not exploded and can be processed as needed by a specific use case.
The other tables follow the same pattern. It is worth noting that FastAPI/ SQLModel/SQLAlchemy can create all tables that where not already there on startup of the server (or when needed).
The database is PostgreSQL. For this upload, bulk inserts are used, following the guidelines of Fastest-Methods-to-Bulk-Insert-Pandas-Dataframe-into-PostgreSQL using psycopg2 copy_expert()
Complement the bundle data
flowchart TB
bundle
bundleJournal
spatialUnit["spatial=Unit: root"]
bundleUnit["bundleUnit: root"]
spatialUnitBundleUnit
spatialUnitBundleUnit --o bundleUnit
spatialUnitBundleUnit --o spatialUnit
bundle --o bundleUnit
bundle --o bundleJournal
bundleUnit --o bundleUnitSite["bundleUnit: site"]
bundleUnitSite --o bundleUnitBuilding["bundleUnit: building"]
bundleUnitBuilding --o bundleUnitStorey["bundleUnit: storey"]
bundleUnitStorey --o bundleUnitSpace["bundleUnit: space"]