graflo.architecture.evolution.sanitize¶
Physical naming for a target database flavor.
A name the database cannot store -- a reserved word, a character it rejects, a
forbidden prefix -- is a fact about the database, not about the graph. So
sanitization never rewrites the logical schema or the ingestion model: it
records the stored name in
:class:~graflo.architecture.schema.database_features.DatabaseProfile, next to
the other physical choices:
vertex_storage_names-- vertex collection / label / tag namesedge_specs[].relation_name-- relation (edge type) namesvertex_property_names-- vertex attribute namesedge_specs[].property_names-- edge attribute names
:func:assign_physical_names computes those names. The write path needs two
views of a schema, and this module builds both:
- :func:
with_physical_names-- the logical schema with a complete profile. Documents keep their logical keys; the writer translates them at the database call. - :func:
materialize_physical_schema-- the schema as the database stores it, for DDL and for backends that take a whole schema. :func:physical_schemacomposes the two.
Attributes¶
IdentifierSanitizer = Callable[[str, str], str]
module-attribute
¶
PROPERTY_SUFFIX = '_attr'
module-attribute
¶
RELATION_SUFFIX = '_relation'
module-attribute
¶
VERTEX_SUFFIX = '_vertex'
module-attribute
¶
logger = logging.getLogger(__name__)
module-attribute
¶
Classes¶
Functions:¶
assign_physical_names(schema, reserved_words, *, db_flavor, profile=None)
¶
Record in the profile the stored name of every element of schema that needs one.
Covers vertex storage names, relation names, and vertex and edge property names. Existing profile names are the starting point, so a name already chosen (by an author or an earlier run) is kept while it stays valid; only names the database would reject are replaced.
Scopes follow the database's namespaces: vertex and relation names share one (a relation may not reuse a vertex's name), each vertex's attributes form one, and so do the attributes of all edges sharing a relation, since TigerGraph declares one attribute list per edge type.
Mutates profile (default schema.db_profile) only; schema.core_schema
is read, never written. Linear in the schema's size: it runs on every write
and schema-aware read, so edge specs are indexed once rather than scanned
per edge, and each distinct name is sanitized once.
Source code in graflo/architecture/evolution/sanitize.py
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | |
identifier_sanitizer(reserved_words, db_flavor)
¶
The name rewriter for db_flavor, or None when every name is valid.
TigerGraph also replaces invalid characters and forbidden prefixes, using the rules its DDL validation rejects on. Other flavors only avoid reserved_words (uppercase), and have none unless a caller supplies them.
Source code in graflo/architecture/evolution/sanitize.py
materialize_physical_schema(schema)
¶
schema as the database stores it: property names are the physical ones.
The profile's property maps are folded into the core schema (properties, identities, secondary identities, indexes, GSQL defaults) and then cleared, so every backend keeps reading names straight off the schema. Storage and relation names already live in the profile and stay there.
Returns schema itself when no property is renamed.
Source code in graflo/architecture/evolution/sanitize.py
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 | |
physical_schema(schema, db_flavor=None)
¶
schema as db_flavor stores it: names filled in, then materialized.
What DDL and any backend call that takes a whole schema should receive. Never mutates schema.
Source code in graflo/architecture/evolution/sanitize.py
with_physical_names(schema, db_flavor=None, *, reserved_words=None)
¶
schema for db_flavor, with a profile that names every stored element.
Names already in the profile win; the rest are filled in by
:func:assign_physical_names. The logical schema is unchanged, so this is
safe to apply on every write: a manifest that was never sanitized deploys
with the same names a sanitized one would record.
Cheap by construction, since it runs on every write and read: only the
profile is copied, and the returned schema shares metadata and
core_schema with schema -- treat it as read-only. When the flavor has
no naming rules and schema already targets it, schema itself is
returned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
schema
|
Schema
|
The authored schema; not mutated. |
required |
db_flavor
|
DBType | None
|
Target flavor. Defaults to |
None
|
reserved_words
|
Iterable[str] | None
|
Override for the flavor's reserved words. |
None
|