Skip to content

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"]