обновление времени изм 2

This commit is contained in:
dv 2026-04-09 11:50:05 +03:00
parent cabc7b865a
commit 1080527bfb
3 changed files with 37 additions and 3 deletions

View file

@ -1,9 +1,10 @@
import csv import csv
import io import io
from datetime import datetime, timezone
from typing import Annotated from typing import Annotated
from fastapi import APIRouter, Depends, File, HTTPException, Query, UploadFile, status from fastapi import APIRouter, Depends, File, HTTPException, Query, UploadFile, status
from sqlalchemy import select from sqlalchemy import select, update as sa_update
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
@ -24,6 +25,12 @@ from app.services import crypto
router = APIRouter(prefix="/api/v1/objects/{obj_id}/devices", tags=["devices"]) router = APIRouter(prefix="/api/v1/objects/{obj_id}/devices", tags=["devices"])
async def _touch_object(db: AsyncSession, obj_id: int) -> None:
await db.execute(
sa_update(Object).where(Object.id == obj_id).values(updated_at=datetime.now(timezone.utc))
)
async def _get_object(db: AsyncSession, obj_id: int) -> Object: async def _get_object(db: AsyncSession, obj_id: int) -> Object:
result = await db.execute(select(Object).where(Object.id == obj_id)) result = await db.execute(select(Object).where(Object.id == obj_id))
obj = result.scalar_one_or_none() obj = result.scalar_one_or_none()
@ -90,6 +97,7 @@ async def create_device(
db.add(device) db.add(device)
await db.flush() await db.flush()
await db.refresh(device) await db.refresh(device)
await _touch_object(db, obj_id)
# reload with rack relationship # reload with rack relationship
result = await db.execute( result = await db.execute(
select(Device).options(selectinload(Device.rack)).where(Device.id == device.id) select(Device).options(selectinload(Device.rack)).where(Device.id == device.id)
@ -117,6 +125,7 @@ async def import_csv(
): ):
await _get_object(db, obj_id) await _get_object(db, obj_id)
preview = await _parse_csv_import(db, obj_id, file, dry_run=False) preview = await _parse_csv_import(db, obj_id, file, dry_run=False)
await _touch_object(db, obj_id)
return DeviceImportResult( return DeviceImportResult(
created=len(preview.would_create), created=len(preview.would_create),
updated=len(preview.would_update), updated=len(preview.would_update),
@ -241,6 +250,7 @@ async def update_device(
await db.flush() await db.flush()
await db.refresh(device) await db.refresh(device)
await _touch_object(db, obj_id)
return device return device
@ -254,6 +264,7 @@ async def delete_all_devices(
result = await db.execute(select(Device).where(Device.object_id == obj_id)) result = await db.execute(select(Device).where(Device.object_id == obj_id))
for device in result.scalars().all(): for device in result.scalars().all():
await db.delete(device) await db.delete(device)
await _touch_object(db, obj_id)
@router.delete("/{device_id}", status_code=status.HTTP_204_NO_CONTENT) @router.delete("/{device_id}", status_code=status.HTTP_204_NO_CONTENT)
@ -265,3 +276,4 @@ async def delete_device(
): ):
device = await _get_device(db, obj_id, device_id) device = await _get_device(db, obj_id, device_id)
await db.delete(device) await db.delete(device)
await _touch_object(db, obj_id)

View file

@ -1,5 +1,7 @@
from datetime import datetime, timezone
from fastapi import APIRouter, Depends, HTTPException, status from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy import select from sqlalchemy import select, update as sa_update
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
@ -12,6 +14,12 @@ from app.schemas.rack import RackCreate, RackRead, RackUpdate
router = APIRouter(prefix="/api/v1/objects/{obj_id}/racks", tags=["racks"]) router = APIRouter(prefix="/api/v1/objects/{obj_id}/racks", tags=["racks"])
async def _touch_object(db: AsyncSession, obj_id: int) -> None:
await db.execute(
sa_update(Object).where(Object.id == obj_id).values(updated_at=datetime.now(timezone.utc))
)
async def _get_object(db: AsyncSession, obj_id: int) -> Object: async def _get_object(db: AsyncSession, obj_id: int) -> Object:
obj = await db.get(Object, obj_id) obj = await db.get(Object, obj_id)
if obj is None: if obj is None:
@ -58,6 +66,7 @@ async def create_rack(
rack = Rack(object_id=obj_id, **body.model_dump()) rack = Rack(object_id=obj_id, **body.model_dump())
db.add(rack) db.add(rack)
await db.flush() await db.flush()
await _touch_object(db, obj_id)
result = await db.execute( result = await db.execute(
select(Rack).options(selectinload(Rack.zone)).where(Rack.id == rack.id) select(Rack).options(selectinload(Rack.zone)).where(Rack.id == rack.id)
) )
@ -76,6 +85,7 @@ async def update_rack(
for field, value in body.model_dump(exclude_unset=True).items(): for field, value in body.model_dump(exclude_unset=True).items():
setattr(rack, field, value) setattr(rack, field, value)
await db.flush() await db.flush()
await _touch_object(db, obj_id)
result = await db.execute( result = await db.execute(
select(Rack).options(selectinload(Rack.zone)).where(Rack.id == rack.id) select(Rack).options(selectinload(Rack.zone)).where(Rack.id == rack.id)
) )
@ -91,3 +101,4 @@ async def delete_rack(
): ):
rack = await _load_rack(db, obj_id, rack_id) rack = await _load_rack(db, obj_id, rack_id)
await db.delete(rack) await db.delete(rack)
await _touch_object(db, obj_id)

View file

@ -1,5 +1,7 @@
from datetime import datetime, timezone
from fastapi import APIRouter, Depends, HTTPException, status from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy import select from sqlalchemy import select, update as sa_update
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from app.dependencies import get_current_user, get_db from app.dependencies import get_current_user, get_db
@ -11,6 +13,12 @@ from app.schemas.zone import ZoneCreate, ZoneRead, ZoneUpdate
router = APIRouter(prefix="/api/v1/objects/{obj_id}/zones", tags=["zones"]) router = APIRouter(prefix="/api/v1/objects/{obj_id}/zones", tags=["zones"])
async def _touch_object(db: AsyncSession, obj_id: int) -> None:
await db.execute(
sa_update(Object).where(Object.id == obj_id).values(updated_at=datetime.now(timezone.utc))
)
async def _get_object(db: AsyncSession, obj_id: int) -> Object: async def _get_object(db: AsyncSession, obj_id: int) -> Object:
obj = await db.get(Object, obj_id) obj = await db.get(Object, obj_id)
if obj is None: if obj is None:
@ -53,6 +61,7 @@ async def create_zone(
db.add(zone) db.add(zone)
await db.flush() await db.flush()
await db.refresh(zone) await db.refresh(zone)
await _touch_object(db, obj_id)
return zone return zone
@ -69,6 +78,7 @@ async def update_zone(
setattr(zone, field, value) setattr(zone, field, value)
await db.flush() await db.flush()
await db.refresh(zone) await db.refresh(zone)
await _touch_object(db, obj_id)
return zone return zone
@ -81,3 +91,4 @@ async def delete_zone(
): ):
zone = await _get_zone(db, obj_id, zone_id) zone = await _get_zone(db, obj_id, zone_id)
await db.delete(zone) await db.delete(zone)
await _touch_object(db, obj_id)