Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "rda_python_common"
version = "2.0.20"
version = "2.1.1"
authors = [
{ name="Zaihua Ji", email="zji@ucar.edu" },
]
Expand Down
17 changes: 9 additions & 8 deletions src/rda_python_common/pg_dbi.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,18 @@
from .pg_log import PgLOG

class PgDBI(PgLOG):

# PostgreSQL specified query timestamp format
fmtyr = lambda fn: "extract(year from {})::int".format(fn)
fmtqt = lambda fn: "extract(quarter from {})::int".format(fn)
fmtmn = lambda fn: "extract(month from {})::int".format(fn)
fmtdt = lambda fn: "date({})".format(fn)
fmtym = lambda fn: "to_char({}, 'yyyy-mm')".format(fn)
fmthr = lambda fn: "extract(hour from {})::int".format(fn)

def __init__(self):
super().__init__() # initialize parent class

# PostgreSQL specified query timestamp format
self.fmtyr = lambda fn=self: "extract(year from {})::int".format(fn)
self.fmtqt = lambda fn=self: "extract(quarter from {})::int".format(fn)
self.fmtmn = lambda fn=self: "extract(month from {})::int".format(fn)
self.fmtdt = lambda fn=self: "date({})".format(fn)
self.fmtym = lambda fn=self: "to_char({}, 'yyyy-mm')".format(fn)
self.fmthr = lambda fn=self: "extract(hour from {})::int".format(fn)
Comment on lines +28 to +33

Copilot AI Mar 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default argument fn=self captures the instance in the lambda’s __defaults__, creating an unnecessary self-reference cycle and making self.fmtyr() (no args) format the PgDBI object instead of a field/expression. These formatters don’t need self; define them without a self default (e.g., require fn), or better, make them @staticmethods to avoid capturing the instance at all.

Suggested change
self.fmtyr = lambda fn=self: "extract(year from {})::int".format(fn)
self.fmtqt = lambda fn=self: "extract(quarter from {})::int".format(fn)
self.fmtmn = lambda fn=self: "extract(month from {})::int".format(fn)
self.fmtdt = lambda fn=self: "date({})".format(fn)
self.fmtym = lambda fn=self: "to_char({}, 'yyyy-mm')".format(fn)
self.fmthr = lambda fn=self: "extract(hour from {})::int".format(fn)
self.fmtyr = lambda fn: "extract(year from {})::int".format(fn)
self.fmtqt = lambda fn: "extract(quarter from {})::int".format(fn)
self.fmtmn = lambda fn: "extract(month from {})::int".format(fn)
self.fmtdt = lambda fn: "date({})".format(fn)
self.fmtym = lambda fn: "to_char({}, 'yyyy-mm')".format(fn)
self.fmthr = lambda fn: "extract(hour from {})::int".format(fn)

Copilot uses AI. Check for mistakes.
Comment on lines +27 to +33

Copilot AI Mar 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The behavior of these SQL timestamp formatter helpers is changing, but there are no tests asserting their outputs or verifying they can be called from an instance/class as intended. Adding a small pytest unit test for PgDBI().fmtyr/fmtqt/... (and, if supported, PgDBI.fmtyr/...) would help prevent regressions in query generation.

Copilot uses AI. Check for mistakes.

Comment on lines 24 to +34

Copilot AI Mar 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These timestamp format helpers used to be available on the class (e.g., PgDBI.fmtyr('col')); moving them into __init__ makes that usage fail because the attributes won’t exist until an instance is created. If external callers may rely on class-level access, consider keeping them as class attributes but mark them as @staticmethod/staticmethod(...) so they work from both the class and instances without method binding issues.

Suggested change
def __init__(self):
super().__init__() # initialize parent class
# PostgreSQL specified query timestamp format
self.fmtyr = lambda fn=self: "extract(year from {})::int".format(fn)
self.fmtqt = lambda fn=self: "extract(quarter from {})::int".format(fn)
self.fmtmn = lambda fn=self: "extract(month from {})::int".format(fn)
self.fmtdt = lambda fn=self: "date({})".format(fn)
self.fmtym = lambda fn=self: "to_char({}, 'yyyy-mm')".format(fn)
self.fmthr = lambda fn=self: "extract(hour from {})::int".format(fn)
# PostgreSQL specified query timestamp format
@staticmethod
def fmtyr(fn):
return "extract(year from {})::int".format(fn)
@staticmethod
def fmtqt(fn):
return "extract(quarter from {})::int".format(fn)
@staticmethod
def fmtmn(fn):
return "extract(month from {})::int".format(fn)
@staticmethod
def fmtdt(fn):
return "date({})".format(fn)
@staticmethod
def fmtym(fn):
return "to_char({}, 'yyyy-mm')".format(fn)
@staticmethod
def fmthr(fn):
return "extract(hour from {})::int".format(fn)
def __init__(self):
super().__init__() # initialize parent class

Copilot uses AI. Check for mistakes.
self.pgdb = None # reference to a connected database object
self.curtran = 0 # 0 - no transaction, 1 - in transaction
self.NMISSES = [] # array of mising userno
Expand Down
Loading