# Core + Security Attributes - Initialization

### Create a new stage for datapancake files (or use an existing stage)

```sql
CREATE STAGE <DATABASE>.<SCHEMA>.DATAPANCAKE_FILES;
```

For more details on creating a stage, see <https://docs.snowflake.com/en/sql-reference/sql/create-stage>

![](https://colony-recorder.s3.amazonaws.com/files/2026-01-19/149fecfb-e559-4576-a13d-88e6b9d9798a/ascreenshot_e2dfe86c61b247be9cccc7da03b6f2a9_text_export.jpeg)

### Copy the Procedure DDL

```sql
CREATE OR REPLACE PROCEDURE <database_name>.<schema_name>.sp_update_datapancake_attribute_metadata_security(
    FILE_PATH string,
    ARCHIVE_PATH string, 
    USER_NAME string
)
RETURNS string
LANGUAGE PYTHON
RUNTIME_VERSION = '3.11'
PACKAGES = ('snowflake-snowpark-python','orjson')
HANDLER = 'update_datapancake_attribute_metadata'
EXECUTE AS CALLER

AS
$$
import snowflake.snowpark as snowpark
import datetime
import traceback
import orjson

def update_datapancake_attribute_metadata(session: snowpark.Session, FILE_PATH: str, ARCHIVE_PATH: str, USER_NAME: str):
    try:

        # Initialize the output variable
        
        attribute_data = ""

        # Step 1: Read the CSV file from the specified Snowflake stage
        # Set skip_header=0 so we can manually extract and process the first row as the header
        
        df = session.read.options({"field_delimiter": ",", "skip_header": 0}).csv(FILE_PATH)
        
        # Step 2: Collect all rows from the file
        
        rows = df.collect()
        if not rows:
            return "No rows found."

        # Step 3: Extract column names from the first row (header)
        # Convert column names to uppercase and strip whitespace
        
        header_row = rows[0]
        header_names = [str(getattr(header_row, f"c{i+1}")).strip().upper() for i in range(len(header_row))]

        # Step 4: Extract all remaining data rows
        
        data_rows = rows[1:]
        if not data_rows:
            return "Only header row found."

        # Step 5: Build a list of records (dicts) using the extracted headers
        
        records = []
        for row in data_rows:
            record = {}
            for i in range(len(header_names)):
                value = getattr(row, f"c{i+1}")
                record[header_names[i]] = str(value).strip() if value not in [None, ""] else None
            records.append(record) 
            
        # Step 6: Serialize the records list as JSON string using orjson
        # Default=str handles values like datetime or decimal types  
        
        attribute_data = orjson.dumps(records,default=str).decode("utf-8")

        # Step 7: Call the DataPancake procedure to update the attribute metadata
        result = session.call("DATAPANCAKE.CORE.UPDATE_ATTRIBUTE_METADATA_SECURITY",USER_NAME, attribute_data, FILE_PATH)
        if result == "Success":

            #Step 8: Optional: Archive the input file to a new location
            if ARCHIVE_PATH is not None and len(ARCHIVE_PATH) > 0 and ARCHIVE_PATH != FILE_PATH:
                session.sql(f"COPY FILES INTO '{ARCHIVE_PATH}' FROM '{FILE_PATH}'").collect()

            #Step 9: Optional - Remove the source file from the stage
            session.sql(f"REMOVE '{FILE_PATH}'").collect()

            #Step 10: Return message showing the successful result
            return f"The DataPancake attribute metadata has been successfully updated and the file has been archived. Processed {len(records)} rows with columns: {', '.join(header_names)}"
        else:
            #Step 10: Return the error message
            return f"Error: {result} and: {rows[1]}"
            
    except Exception as e:
        return f"Error: {str(e)} with a trace of: {traceback.format_exc()}"
$$;
```

### Paste the DDL and modify the database and schema name

{% hint style="info" %}
If you changed the name during install, modify DataPancake application database name.
{% endhint %}

![](https://colony-recorder.s3.amazonaws.com/files/2026-01-19/08a48753-77e8-42d4-8b26-bfd3975cf655/ascreenshot_af59fff4a3d74acbae85aa358dcf8b50_text_export.jpeg)

![](https://colony-recorder.s3.amazonaws.com/files/2026-01-19/0b3bb1f7-ddda-4a94-a866-ef18601b3873/ascreenshot_ef7432d644884206ae0391af2b65dfff_text_export.jpeg)

### Execute the create stored procedure statement

![](https://colony-recorder.s3.amazonaws.com/files/2026-01-19/e1381ebe-bafc-4c6a-8ca6-4807c00ff171/ascreenshot_dfc701671c0949b990f489f9aff23817_text_export.jpeg)

### Verify the stored procedure was created successfully

![](https://colony-recorder.s3.amazonaws.com/files/2026-01-19/479a2eb6-abce-4484-a932-e4159af96271/ascreenshot_b35428f606ee428991445782033c9daf_text_export.jpeg)

## Next Steps

[Attribute Metadata Bulk Updates (Security) - Execute](https://docs.datapancake.com/guides/how-to-guides-bulk-upsert-via-csv/usage/core-+-security-attributes-bulk-update)
