Import the wilm agent store, WINC adoption work and batches CLI, with four fixes
This commit is contained in:
@@ -23,6 +23,8 @@ from .setting import Setting
|
||||
from .auditlog import AuditLog
|
||||
from .customfield import CustomField, CustomFieldValue
|
||||
from .apitoken import ApiToken
|
||||
from .importbatch import (ImportBatch, ImportJournalEntry, BATCH_APPLIED,
|
||||
BATCH_UNDONE, OP_UPDATE, OP_INSERT)
|
||||
|
||||
__all__ = [
|
||||
# Base
|
||||
@@ -82,4 +84,11 @@ __all__ = [
|
||||
'CustomFieldValue',
|
||||
# Personal API tokens
|
||||
'ApiToken',
|
||||
# Import batch + journal (reversible bulk imports)
|
||||
'ImportBatch',
|
||||
'ImportJournalEntry',
|
||||
'BATCH_APPLIED',
|
||||
'BATCH_UNDONE',
|
||||
'OP_UPDATE',
|
||||
'OP_INSERT',
|
||||
]
|
||||
|
||||
86
shopdb/core/models/importbatch.py
Normal file
86
shopdb/core/models/importbatch.py
Normal file
@@ -0,0 +1,86 @@
|
||||
"""Import batch + journal models (reversible bulk imports).
|
||||
|
||||
PLATFORM-LEVEL, IMPORT-AGNOSTIC. These two tables let any bulk-import writer
|
||||
record exactly what it changed so the change can be reversed later. Nothing here
|
||||
knows about Maximo, WINC, machines, or any one source: an importer records
|
||||
primitive mutations (set column X on row Y, or insert row Y) tied to a batch id,
|
||||
and a generic undo replays them in reverse.
|
||||
|
||||
importbatches one row per approved write - the identity that approval, the
|
||||
write, and the eventual undo all reference (the same value
|
||||
the approval packet calls batchid).
|
||||
importjournalentries one row per primitive mutation the writer made, ordered so
|
||||
undo can reverse them (inserts removed after the updates that
|
||||
pointed at them are reverted).
|
||||
|
||||
The undo contract, kept deliberately conservative:
|
||||
- update is reverted only if the cell still holds the value we wrote; a value a
|
||||
human changed since is left as-is and reported (never clobbered).
|
||||
- insert is hard-deleted, but ONLY the row this batch created and only when
|
||||
nothing outside the batch still references it.
|
||||
"""
|
||||
|
||||
from shopdb.extensions import db
|
||||
|
||||
|
||||
# Batch lifecycle.
|
||||
BATCH_APPLIED = 'applied'
|
||||
BATCH_UNDONE = 'undone'
|
||||
|
||||
# Journal operation kinds.
|
||||
OP_UPDATE = 'update'
|
||||
OP_INSERT = 'insert'
|
||||
|
||||
|
||||
class ImportBatch(db.Model):
|
||||
"""One approved import write. The batchid is the approval packet's batchid,
|
||||
carried through write and undo so all three reference one identity."""
|
||||
__tablename__ = 'importbatches'
|
||||
|
||||
batchid = db.Column(db.String(36), primary_key=True)
|
||||
kind = db.Column(db.String(64), nullable=False)
|
||||
planhash = db.Column(db.String(64), nullable=False)
|
||||
rowcount = db.Column(db.Integer, nullable=False, default=0)
|
||||
createdat = db.Column(db.DateTime, nullable=False)
|
||||
createdby = db.Column(db.String(100), nullable=True)
|
||||
status = db.Column(db.String(16), nullable=False, default=BATCH_APPLIED)
|
||||
undoneat = db.Column(db.DateTime, nullable=True)
|
||||
|
||||
entries = db.relationship(
|
||||
'ImportJournalEntry',
|
||||
backref='batch',
|
||||
cascade='all, delete-orphan',
|
||||
order_by='ImportJournalEntry.sequence',
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<ImportBatch {self.kind} {self.batchid} {self.status}>"
|
||||
|
||||
|
||||
class ImportJournalEntry(db.Model):
|
||||
"""One reversible primitive mutation made by an import writer."""
|
||||
__tablename__ = 'importjournalentries'
|
||||
|
||||
# SQLite only autoincrements a plain INTEGER PRIMARY KEY, not BIGINT, so the
|
||||
# test database needs the Integer variant while MySQL keeps BIGINT for range.
|
||||
entryid = db.Column(
|
||||
db.BigInteger().with_variant(db.Integer, 'sqlite'),
|
||||
primary_key=True)
|
||||
batchid = db.Column(
|
||||
db.String(36),
|
||||
db.ForeignKey('importbatches.batchid', ondelete='CASCADE'),
|
||||
nullable=False,
|
||||
index=True,
|
||||
)
|
||||
sequence = db.Column(db.Integer, nullable=False)
|
||||
operation = db.Column(db.String(16), nullable=False)
|
||||
targettable = db.Column(db.String(64), nullable=False)
|
||||
targetid = db.Column(db.BigInteger, nullable=False)
|
||||
columnname = db.Column(db.String(64), nullable=True)
|
||||
oldvalue = db.Column(db.Text, nullable=True)
|
||||
newvalue = db.Column(db.Text, nullable=True)
|
||||
isreverted = db.Column(db.Boolean, nullable=False, default=False)
|
||||
|
||||
def __repr__(self):
|
||||
return (f"<ImportJournalEntry {self.operation} "
|
||||
f"{self.targettable}.{self.targetid}>")
|
||||
Reference in New Issue
Block a user