I'm trying to calculate the maximum length of NUMERIC columns in a postgres db. There are a number of tables in the db, and most of those tables contain a number of numeric columns.
I'm importing a fairly large number of json data into the database. SQLModel or pydantic fails to insert numeric fields if the destination column precision/scale is less than that of the input. For now, I'm seeding data to generic NUMERIC(16,5)
columns, but I'd like to reduce storage space by optimizing column sizes. (mine is a semi-readonly dataset, the column sizes won't differ much in future)
For reference, following is my abortive stab at solving the problem...
SELECT
table_schema,
TABLE_NAME,
COLUMN_NAME,
(
xpath (
'/row/max/text()',
query_to_xml (
format (
'SELECT LENGTH ( CAST ( MAX ( %I ) AS CHARACTER VARYING ( 40 ) ) ) from %I.%I',
COLUMN_NAME,
table_schema,
TABLE_NAME
),
TRUE,
TRUE,
''
)
)
) [ 1 ] :: TEXT :: INT AS max_length
FROM
information_schema.COLUMNS
WHERE
table_schema = 'public'
AND data_type = 'numeric'
ORDER BY
table_schema,
TABLE_NAME,
COLUMN_NAME;
Even better would be to split the max column lengths into precision & scale.
numeric(3,2)
or innumeric(100,50)
doesn't matter space-wise. The more digits, the more space the number takes.