修复:保留 PostgreSQL 时间微秒精度

This commit is contained in:
焦龙言
2026-07-27 13:33:08 +08:00
parent b858340890
commit 7a786800bd
2 changed files with 85 additions and 34 deletions
@@ -1082,9 +1082,9 @@ create table biz_strain (
strain_name varchar(100) not null, strain_name varchar(100) not null,
status char(1) not null default '0', status char(1) not null default '0',
create_by varchar(64) default '', create_by varchar(64) default '',
create_time timestamp(0), create_time timestamp without time zone,
update_by varchar(64) default '', update_by varchar(64) default '',
update_time timestamp(0), update_time timestamp without time zone,
remark varchar(500) default null, remark varchar(500) default null,
primary key (strain_id), primary key (strain_id),
constraint uq_biz_strain_code unique (strain_code), constraint uq_biz_strain_code unique (strain_code),
@@ -1098,9 +1098,9 @@ create table biz_warehouse (
address varchar(500), address varchar(500),
status char(1) not null default '0', status char(1) not null default '0',
create_by varchar(64) default '', create_by varchar(64) default '',
create_time timestamp(0), create_time timestamp without time zone,
update_by varchar(64) default '', update_by varchar(64) default '',
update_time timestamp(0), update_time timestamp without time zone,
remark varchar(500) default null, remark varchar(500) default null,
primary key (warehouse_id), primary key (warehouse_id),
constraint uq_biz_warehouse_code unique (warehouse_code), constraint uq_biz_warehouse_code unique (warehouse_code),
@@ -1113,9 +1113,9 @@ create table biz_customer (
customer_name varchar(100) not null, customer_name varchar(100) not null,
status char(1) not null default '0', status char(1) not null default '0',
create_by varchar(64) default '', create_by varchar(64) default '',
create_time timestamp(0), create_time timestamp without time zone,
update_by varchar(64) default '', update_by varchar(64) default '',
update_time timestamp(0), update_time timestamp without time zone,
remark varchar(500) default null, remark varchar(500) default null,
primary key (customer_id), primary key (customer_id),
constraint uq_biz_customer_code unique (customer_code), constraint uq_biz_customer_code unique (customer_code),
@@ -1130,9 +1130,9 @@ create table biz_customer_site (
address varchar(500), address varchar(500),
status char(1) not null default '0', status char(1) not null default '0',
create_by varchar(64) default '', create_by varchar(64) default '',
create_time timestamp(0), create_time timestamp without time zone,
update_by varchar(64) default '', update_by varchar(64) default '',
update_time timestamp(0), update_time timestamp without time zone,
remark varchar(500) default null, remark varchar(500) default null,
primary key (site_id), primary key (site_id),
constraint uq_biz_customer_site_customer_code unique (customer_id, site_code), constraint uq_biz_customer_site_customer_code unique (customer_id, site_code),
@@ -1147,9 +1147,9 @@ create table biz_production_line (
line_name varchar(100) not null, line_name varchar(100) not null,
status char(1) not null default '0', status char(1) not null default '0',
create_by varchar(64) default '', create_by varchar(64) default '',
create_time timestamp(0), create_time timestamp without time zone,
update_by varchar(64) default '', update_by varchar(64) default '',
update_time timestamp(0), update_time timestamp without time zone,
remark varchar(500) default null, remark varchar(500) default null,
primary key (line_id), primary key (line_id),
constraint uq_biz_production_line_site_code unique (site_id, line_code), constraint uq_biz_production_line_site_code unique (site_id, line_code),
@@ -1164,9 +1164,9 @@ create table biz_pallet (
capacity_packages integer not null, capacity_packages integer not null,
asset_status char(1) not null default '0', asset_status char(1) not null default '0',
create_by varchar(64) default '', create_by varchar(64) default '',
create_time timestamp(0), create_time timestamp without time zone,
update_by varchar(64) default '', update_by varchar(64) default '',
update_time timestamp(0), update_time timestamp without time zone,
remark varchar(500) default null, remark varchar(500) default null,
primary key (pallet_id), primary key (pallet_id),
constraint uq_biz_pallet_code unique (pallet_code), constraint uq_biz_pallet_code unique (pallet_code),
@@ -1179,7 +1179,7 @@ create table biz_user_warehouse (
user_id bigint not null, user_id bigint not null,
warehouse_id bigint not null, warehouse_id bigint not null,
create_by varchar(64) default '', create_by varchar(64) default '',
create_time timestamp(0), create_time timestamp without time zone,
primary key (user_id, warehouse_id), primary key (user_id, warehouse_id),
constraint fk_biz_user_warehouse_user foreign key (user_id) references sys_user(user_id), constraint fk_biz_user_warehouse_user foreign key (user_id) references sys_user(user_id),
constraint fk_biz_user_warehouse_warehouse foreign key (warehouse_id) references biz_warehouse(warehouse_id) constraint fk_biz_user_warehouse_warehouse foreign key (warehouse_id) references biz_warehouse(warehouse_id)
@@ -1189,7 +1189,7 @@ create table biz_user_site (
user_id bigint not null, user_id bigint not null,
site_id bigint not null, site_id bigint not null,
create_by varchar(64) default '', create_by varchar(64) default '',
create_time timestamp(0), create_time timestamp without time zone,
primary key (user_id, site_id), primary key (user_id, site_id),
constraint fk_biz_user_site_user foreign key (user_id) references sys_user(user_id), constraint fk_biz_user_site_user foreign key (user_id) references sys_user(user_id),
constraint fk_biz_user_site_site foreign key (site_id) references biz_customer_site(site_id) constraint fk_biz_user_site_site foreign key (site_id) references biz_customer_site(site_id)
@@ -1203,11 +1203,11 @@ create table biz_inbound_order (
confirm_idempotency_key varchar(64), confirm_idempotency_key varchar(64),
confirm_request_hash varchar(64), confirm_request_hash varchar(64),
confirmed_by bigint, confirmed_by bigint,
confirmed_at timestamp(0), confirmed_at timestamp without time zone,
create_by varchar(64) default '', create_by varchar(64) default '',
create_time timestamp(0), create_time timestamp without time zone,
update_by varchar(64) default '', update_by varchar(64) default '',
update_time timestamp(0), update_time timestamp without time zone,
remark varchar(500) default null, remark varchar(500) default null,
primary key (inbound_id), primary key (inbound_id),
constraint uq_biz_inbound_order_no unique (inbound_no), constraint uq_biz_inbound_order_no unique (inbound_no),
@@ -1222,7 +1222,7 @@ create table biz_inbound_item (
inbound_id bigint not null, inbound_id bigint not null,
pallet_id bigint not null, pallet_id bigint not null,
create_by varchar(64) default '', create_by varchar(64) default '',
create_time timestamp(0), create_time timestamp without time zone,
primary key (inbound_item_id), primary key (inbound_item_id),
constraint uq_biz_inbound_item_order_pallet unique (inbound_id, pallet_id), constraint uq_biz_inbound_item_order_pallet unique (inbound_id, pallet_id),
constraint fk_biz_inbound_item_order foreign key (inbound_id) references biz_inbound_order(inbound_id), constraint fk_biz_inbound_item_order foreign key (inbound_id) references biz_inbound_order(inbound_id),
@@ -1241,15 +1241,15 @@ create table biz_filling_record (
package_spec varchar(64) not null, package_spec varchar(64) not null,
initial_packages integer not null, initial_packages integer not null,
active_slot varchar(16), active_slot varchar(16),
closed_at timestamp(0), closed_at timestamp without time zone,
idempotency_key varchar(64) not null, idempotency_key varchar(64) not null,
request_hash varchar(64) not null, request_hash varchar(64) not null,
operator_id bigint not null, operator_id bigint not null,
operated_at timestamp(0) not null, operated_at timestamp without time zone not null,
create_by varchar(64) default '', create_by varchar(64) default '',
create_time timestamp(0), create_time timestamp without time zone,
update_by varchar(64) default '', update_by varchar(64) default '',
update_time timestamp(0), update_time timestamp without time zone,
remark varchar(500) default null, remark varchar(500) default null,
primary key (filling_id), primary key (filling_id),
constraint uq_biz_filling_record_no unique (filling_no), constraint uq_biz_filling_record_no unique (filling_no),
@@ -1272,11 +1272,11 @@ create table biz_shipment_order (
confirm_idempotency_key varchar(64), confirm_idempotency_key varchar(64),
confirm_request_hash varchar(64), confirm_request_hash varchar(64),
confirmed_by bigint, confirmed_by bigint,
confirmed_at timestamp(0), confirmed_at timestamp without time zone,
create_by varchar(64) default '', create_by varchar(64) default '',
create_time timestamp(0), create_time timestamp without time zone,
update_by varchar(64) default '', update_by varchar(64) default '',
update_time timestamp(0), update_time timestamp without time zone,
remark varchar(500) default null, remark varchar(500) default null,
primary key (shipment_id), primary key (shipment_id),
constraint uq_biz_shipment_order_no unique (shipment_no), constraint uq_biz_shipment_order_no unique (shipment_no),
@@ -1294,7 +1294,7 @@ create table biz_shipment_item (
active_filling_id bigint, active_filling_id bigint,
package_qty integer, package_qty integer,
create_by varchar(64) default '', create_by varchar(64) default '',
create_time timestamp(0), create_time timestamp without time zone,
primary key (shipment_item_id), primary key (shipment_item_id),
constraint uq_biz_shipment_item_order_pallet unique (shipment_id, pallet_id), constraint uq_biz_shipment_item_order_pallet unique (shipment_id, pallet_id),
constraint ck_biz_shipment_item_package_qty check (package_qty is null or package_qty > 0), constraint ck_biz_shipment_item_package_qty check (package_qty is null or package_qty > 0),
@@ -1315,7 +1315,7 @@ create table biz_usage_record (
idempotency_key varchar(64) not null, idempotency_key varchar(64) not null,
request_hash varchar(64) not null, request_hash varchar(64) not null,
operator_id bigint not null, operator_id bigint not null,
occurred_at timestamp(0) not null, occurred_at timestamp without time zone not null,
primary key (usage_id), primary key (usage_id),
constraint uq_biz_usage_record_no unique (usage_no), constraint uq_biz_usage_record_no unique (usage_no),
constraint uq_biz_usage_record_idempotency unique (idempotency_key), constraint uq_biz_usage_record_idempotency unique (idempotency_key),
@@ -1339,13 +1339,13 @@ create table biz_return_order (
confirm_idempotency_key varchar(64), confirm_idempotency_key varchar(64),
confirm_request_hash varchar(64), confirm_request_hash varchar(64),
requested_by bigint not null, requested_by bigint not null,
requested_at timestamp(0) not null, requested_at timestamp without time zone not null,
confirmed_by bigint, confirmed_by bigint,
confirmed_at timestamp(0), confirmed_at timestamp without time zone,
create_by varchar(64) default '', create_by varchar(64) default '',
create_time timestamp(0), create_time timestamp without time zone,
update_by varchar(64) default '', update_by varchar(64) default '',
update_time timestamp(0), update_time timestamp without time zone,
remark varchar(500) default null, remark varchar(500) default null,
primary key (return_id), primary key (return_id),
constraint uq_biz_return_order_no unique (return_no), constraint uq_biz_return_order_no unique (return_no),
@@ -1365,7 +1365,7 @@ create table biz_return_item (
active_filling_id_snapshot bigint, active_filling_id_snapshot bigint,
remaining_packages_snapshot integer not null, remaining_packages_snapshot integer not null,
create_by varchar(64) default '', create_by varchar(64) default '',
create_time timestamp(0), create_time timestamp without time zone,
primary key (return_item_id), primary key (return_item_id),
constraint uq_biz_return_item_order_pallet unique (return_id, pallet_id), constraint uq_biz_return_item_order_pallet unique (return_id, pallet_id),
constraint ck_biz_return_item_remaining_packages_snapshot check (remaining_packages_snapshot >= 0), constraint ck_biz_return_item_remaining_packages_snapshot check (remaining_packages_snapshot >= 0),
@@ -1392,7 +1392,7 @@ create table biz_pallet_event (
before_remaining_packages integer not null, before_remaining_packages integer not null,
after_remaining_packages integer not null, after_remaining_packages integer not null,
operator_id bigint not null, operator_id bigint not null,
occurred_at timestamp(0) not null, occurred_at timestamp without time zone not null,
idempotency_key varchar(64) not null, idempotency_key varchar(64) not null,
request_hash varchar(64) not null, request_hash varchar(64) not null,
primary key (event_id), primary key (event_id),
@@ -1424,7 +1424,7 @@ create table biz_pallet_inventory (
remaining_packages integer not null default 0, remaining_packages integer not null default 0,
last_event_id bigint, last_event_id bigint,
version integer not null default 0, version integer not null default 0,
updated_at timestamp(0) not null, updated_at timestamp without time zone not null,
primary key (pallet_id), primary key (pallet_id),
constraint ck_biz_pallet_inventory_flow_state check ( constraint ck_biz_pallet_inventory_flow_state check (
flow_state in ( flow_state in (
@@ -165,6 +165,27 @@ EXPECTED_COLUMNS = {
}, },
} }
EXPECTED_DATETIME_COLUMNS = {
'biz_strain': {'create_time', 'update_time'},
'biz_warehouse': {'create_time', 'update_time'},
'biz_customer': {'create_time', 'update_time'},
'biz_customer_site': {'create_time', 'update_time'},
'biz_production_line': {'create_time', 'update_time'},
'biz_pallet': {'create_time', 'update_time'},
'biz_user_warehouse': {'create_time'},
'biz_user_site': {'create_time'},
'biz_inbound_order': {'confirmed_at', 'create_time', 'update_time'},
'biz_inbound_item': {'create_time'},
'biz_filling_record': {'closed_at', 'operated_at', 'create_time', 'update_time'},
'biz_shipment_order': {'confirmed_at', 'create_time', 'update_time'},
'biz_shipment_item': {'create_time'},
'biz_usage_record': {'occurred_at'},
'biz_return_order': {'requested_at', 'confirmed_at', 'create_time', 'update_time'},
'biz_return_item': {'create_time'},
'biz_pallet_inventory': {'updated_at'},
'biz_pallet_event': {'occurred_at'},
}
EXPECTED_PRIMARY_KEYS = { EXPECTED_PRIMARY_KEYS = {
'biz_strain': ('strain_id',), 'biz_strain': ('strain_id',),
'biz_warehouse': ('warehouse_id',), 'biz_warehouse': ('warehouse_id',),
@@ -577,6 +598,17 @@ def _table_contract(
return columns, primary_key, unique_keys, foreign_keys, checks return columns, primary_key, unique_keys, foreign_keys, checks
def _column_definitions(body: str) -> dict[str, str]:
definitions = {}
reserved = {'constraint', 'primary', 'unique', 'foreign', 'check', 'key', 'index'}
for clause in _split_values(body):
clean = clause.strip()
identifier_match = re.match(r'[`"]?([a-z_][a-z0-9_]*)[`"]?', clean, flags=re.I)
if identifier_match and identifier_match.group(1).lower() not in reserved:
definitions[identifier_match.group(1).lower()] = clean
return definitions
def _business_menu_rows(sql: str) -> dict[int, list]: def _business_menu_rows(sql: str) -> dict[int, list]:
rows = _insert_rows(sql, 'sys_menu') rows = _insert_rows(sql, 'sys_menu')
selected = [row for row in rows if row and str(row[0]).isdigit() and int(row[0]) in BUSINESS_MENU_IDS] selected = [row for row in rows if row and str(row[0]).isdigit() and int(row[0]) in BUSINESS_MENU_IDS]
@@ -607,6 +639,25 @@ class SqlContractTest(unittest.TestCase):
self.assertEqual(EXPECTED_FOREIGN_KEYS[table], foreign_keys) self.assertEqual(EXPECTED_FOREIGN_KEYS[table], foreign_keys)
self.assertEqual(EXPECTED_CHECKS[table], checks) self.assertEqual(EXPECTED_CHECKS[table], checks)
def test_postgres_business_datetimes_preserve_default_microsecond_precision(self) -> None:
self.assertEqual(34, sum(len(columns) for columns in EXPECTED_DATETIME_COLUMNS.values()))
tables = _create_table_bodies((SQL_ROOT / 'shierfeng-fastapi-pg.sql').read_text(encoding='utf-8'))
zero_precision_columns = []
for table, expected_columns in EXPECTED_DATETIME_COLUMNS.items():
definitions = _column_definitions(tables[table])
actual_columns = {
column
for column, definition in definitions.items()
if re.search(r'\btimestamp\b', definition, flags=re.I)
}
self.assertEqual(expected_columns, actual_columns, table)
for column in expected_columns:
definition = definitions[column]
self.assertRegex(definition, r'\btimestamp(?:\s+without\s+time\s+zone)?\b')
if re.search(r'\btimestamp\s*\(\s*0\s*\)', definition, flags=re.I):
zero_precision_columns.append(f'{table}.{column}')
self.assertEqual([], sorted(zero_precision_columns))
def test_initializers_define_fixed_business_menus_and_permissions(self) -> None: def test_initializers_define_fixed_business_menus_and_permissions(self) -> None:
expected_permissions = {page[-1] for page in EXPECTED_PAGES.values()} | { expected_permissions = {page[-1] for page in EXPECTED_PAGES.values()} | {
button[-1] for button in EXPECTED_BUTTONS.values() button[-1] for button in EXPECTED_BUTTONS.values()