table.default_values property, closes #475

Refs #468
This commit is contained in:
Simon Willison 2022-08-27 15:41:10 -07:00
commit 36ffcafb1a
3 changed files with 57 additions and 0 deletions

View file

@ -1802,6 +1802,16 @@ The ``.columns_dict`` property returns a dictionary version of the columns with
>>> db["PlantType"].columns_dict
{'id': <class 'int'>, 'value': <class 'str'>}
.. _python_api_introspection_default_values:
.default_values
---------------
The ``.default_values`` property returns a dictionary of default values for each column that has a default::
>>> db["table_with_defaults"].default_values
{'score': 5}
.. _python_api_introspection_pks:
.pks

View file

@ -9,6 +9,7 @@ from .utils import (
progressbar,
find_spatialite,
)
import binascii
from collections import namedtuple
from collections.abc import Mapping
import contextlib
@ -1458,6 +1459,15 @@ class Table(Queryable):
"``{trigger_name: sql}`` dictionary of triggers defined on this table."
return {trigger.name: trigger.sql for trigger in self.triggers}
@property
def default_values(self) -> Dict[str, Any]:
"``{column_name: default_value}`` dictionary of default values for columns in this table."
return {
column.name: _decode_default_value(column.default_value)
for column in self.columns
if column.default_value is not None
}
@property
def strict(self) -> bool:
"Is this a STRICT table?"
@ -3527,3 +3537,22 @@ def fix_square_braces(records: Iterable[Dict[str, Any]]):
}
else:
yield record
def _decode_default_value(value):
if value.startswith("'") and value.endswith("'"):
# It's a string
return value[1:-1]
if value.isdigit():
# It's an integer
return int(value)
if value.startswith("X'") and value.endswith("'"):
# It's a binary string, stored as hex
to_decode = value[2:-1]
return binascii.unhexlify(to_decode)
# If it is a string containing a floating point number:
try:
return float(value)
except ValueError:
pass
return value

View file

@ -299,3 +299,21 @@ def test_table_strict(fresh_db, create_table, expected_strict):
fresh_db.execute(create_table)
table = fresh_db["t"]
assert table.strict == expected_strict
@pytest.mark.parametrize(
"value",
(
1,
1.3,
"foo",
True,
b"binary",
),
)
def test_table_default_values(fresh_db, value):
fresh_db["default_values"].insert(
{"nodefault": 1, "value": value}, defaults={"value": value}
)
default_values = fresh_db["default_values"].default_values
assert default_values == {"value": value}