Skip to content

Commit ef6c66d

Browse files
Remove legacy log table and bump version to 2.0.0a1
- Remove Log class from table.py - Remove _log property and all _log() calls from Table class - Remove log property from Schema class - Remove ~log table special handling in heading.py - Remove test_log.py - Bump version from 0.14.6 to 2.0.0a1 - Remove version length assertion (was only for log table compatibility) The log table was an outdated approach to event logging. Modern systems should use standard Python logging, external log aggregation services, or database audit logs instead. Test results: 470 passed, 2 skipped 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent 7d32ea1 commit ef6c66d

File tree

5 files changed

+2
-111
lines changed

5 files changed

+2
-111
lines changed

src/datajoint/heading.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,9 +230,6 @@ def _init_from_database(self):
230230
as_dict=True,
231231
).fetchone()
232232
if info is None:
233-
if table_name == "~log":
234-
logger.warning("Could not create the ~log table")
235-
return
236233
raise DataJointError(
237234
"The table `{database}`.`{table_name}` is not defined.".format(table_name=table_name, database=database)
238235
)

src/datajoint/schemas.py

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from .heading import Heading
1212
from .jobs import JobTable
1313
from .settings import config
14-
from .table import FreeTable, Log, lookup_class_name
14+
from .table import FreeTable, lookup_class_name
1515
from .user_tables import Computed, Imported, Lookup, Manual, Part, _get_tier
1616
from .utils import to_camel_case, user_choice
1717

@@ -63,7 +63,6 @@ def __init__(
6363
:param add_objects: a mapping with additional objects to make available to the context in which table classes
6464
are declared.
6565
"""
66-
self._log = None
6766
self.connection = connection
6867
self.database = None
6968
self.context = context
@@ -134,8 +133,6 @@ def activate(
134133
raise DataJointError(
135134
"Schema `{name}` does not exist and could not be created. Check permissions.".format(name=schema_name)
136135
)
137-
else:
138-
self.log("created")
139136
self.connection.register(self)
140137

141138
# decorate all tables already decorated
@@ -225,13 +222,6 @@ def _decorate_table(self, table_class, context, assert_declared=False):
225222
else:
226223
instance.insert(contents, skip_duplicates=True)
227224

228-
@property
229-
def log(self):
230-
self._assert_exists()
231-
if self._log is None:
232-
self._log = Log(self.connection, self.database)
233-
return self._log
234-
235225
def __repr__(self):
236226
return "Schema `{name}`\n".format(name=self.database)
237227

src/datajoint/table.py

Lines changed: 0 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import json
66
import logging
77
import mimetypes
8-
import platform
98
import re
109
import uuid
1110
from datetime import datetime, timezone
@@ -29,7 +28,6 @@
2928
from .staged_insert import staged_insert1 as _staged_insert1
3029
from .storage import StorageBackend, build_object_path, verify_or_create_store_metadata
3130
from .utils import get_master, is_camel_case, user_choice
32-
from .version import __version__ as version
3331

3432
logger = logging.getLogger(__name__.split(".")[0])
3533

@@ -68,7 +66,6 @@ class Table(QueryExpression):
6866
"""
6967

7068
_table_name = None # must be defined in subclass
71-
_log_ = None # placeholder for the Log table object
7269

7370
# These properties must be set by the schema decorator (schemas.py) at class level
7471
# or by FreeTable at instance level
@@ -113,8 +110,6 @@ def declare(self, context=None):
113110
except AccessError:
114111
# skip if no create privilege
115112
pass
116-
else:
117-
self._log("Declared " + self.full_table_name)
118113

119114
def alter(self, prompt=True, context=None):
120115
"""
@@ -144,7 +139,6 @@ def alter(self, prompt=True, context=None):
144139
self.__class__._heading = Heading(table_info=self.heading.table_info)
145140
if prompt:
146141
logger.info("Table altered")
147-
self._log("Altered " + self.full_table_name)
148142

149143
def from_clause(self):
150144
"""
@@ -261,16 +255,6 @@ def full_table_name(self):
261255
)
262256
return r"`{0:s}`.`{1:s}`".format(self.database, self.table_name)
263257

264-
@property
265-
def _log(self):
266-
if self._log_ is None:
267-
self._log_ = Log(
268-
self.connection,
269-
database=self.database,
270-
skip_logging=self.table_name.startswith("~"),
271-
)
272-
return self._log_
273-
274258
@property
275259
def object_storage(self) -> StorageBackend | None:
276260
"""Get the default object storage backend for this table."""
@@ -627,7 +611,6 @@ def delete_quick(self, get_count=False):
627611
query = "DELETE FROM " + self.full_table_name + self.where_clause()
628612
self.connection.query(query)
629613
count = self.connection.query("SELECT ROW_COUNT()").fetchone()[0] if get_count else None
630-
self._log(query[:255])
631614
return count
632615

633616
def delete(
@@ -804,7 +787,6 @@ def drop_quick(self):
804787
query = "DROP TABLE %s" % self.full_table_name
805788
self.connection.query(query)
806789
logger.info("Dropped table %s" % self.full_table_name)
807-
self._log(query[:255])
808790
else:
809791
logger.info("Nothing to drop: table %s is not declared" % self.full_table_name)
810792

@@ -1122,76 +1104,3 @@ def __init__(self, conn, full_table_name):
11221104

11231105
def __repr__(self):
11241106
return "FreeTable(`%s`.`%s`)\n" % (self.database, self._table_name) + super().__repr__()
1125-
1126-
1127-
class Log(Table):
1128-
"""
1129-
The log table for each schema.
1130-
Instances are callable. Calls log the time and identifying information along with the event.
1131-
1132-
:param skip_logging: if True, then log entry is skipped by default. See __call__
1133-
"""
1134-
1135-
_table_name = "~log"
1136-
1137-
def __init__(self, conn, database, skip_logging=False):
1138-
self.database = database
1139-
self.skip_logging = skip_logging
1140-
self._connection = conn
1141-
self._heading = Heading(table_info=dict(conn=conn, database=database, table_name=self.table_name, context=None))
1142-
self._support = [self.full_table_name]
1143-
1144-
self._definition = """ # event logging table for `{database}`
1145-
id :int unsigned auto_increment # event order id
1146-
---
1147-
timestamp = CURRENT_TIMESTAMP : timestamp # event timestamp
1148-
version :varchar(12) # datajoint version
1149-
user :varchar(255) # user@host
1150-
host="" :varchar(255) # system hostname
1151-
event="" :varchar(255) # event message
1152-
""".format(database=database)
1153-
1154-
super().__init__()
1155-
1156-
if not self.is_declared:
1157-
self.declare()
1158-
self.connection.dependencies.clear()
1159-
self._user = self.connection.get_user()
1160-
1161-
@property
1162-
def definition(self):
1163-
return self._definition
1164-
1165-
def __call__(self, event, skip_logging=None):
1166-
"""
1167-
1168-
:param event: string to write into the log table
1169-
:param skip_logging: If True then do not log. If None, then use self.skip_logging
1170-
"""
1171-
skip_logging = self.skip_logging if skip_logging is None else skip_logging
1172-
if not skip_logging:
1173-
try:
1174-
self.insert1(
1175-
dict(
1176-
user=self._user,
1177-
version=version + "py",
1178-
host=platform.uname().node,
1179-
event=event,
1180-
),
1181-
skip_duplicates=True,
1182-
ignore_extra_fields=True,
1183-
)
1184-
except DataJointError:
1185-
logger.info("could not log event in table ~log")
1186-
1187-
def delete(self):
1188-
"""
1189-
bypass interactive prompts and cascading dependencies
1190-
1191-
:return: number of deleted items
1192-
"""
1193-
return self.delete_quick(get_count=True)
1194-
1195-
def drop(self):
1196-
"""bypass interactive prompts and cascading dependencies"""
1197-
self.drop_quick()

src/datajoint/version.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
# version bump auto managed by Github Actions:
22
# label_prs.yaml(prep), release.yaml(bump), post_release.yaml(edit)
33
# manually set this version will be eventually overwritten by the above actions
4-
__version__ = "0.14.6"
5-
6-
assert len(__version__) <= 10 # The log table limits version to the 10 characters
4+
__version__ = "2.0.0a1"

tests/test_log.py

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)