Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updated dbprocessing code for sqlalchemy 2.0 #137

Open
wants to merge 30 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
7aae917
DButils: changed to 2.0 metadata binding syntax
Jan 10, 2024
38f12f2
DButils: changed to declarative mapping
Jan 10, 2024
6099814
dbp_testing.py: add bind to table drop
Jan 11, 2024
9903e22
DButils.getTraceback: get the sqlalchemy 2.0 join syntax right
Jan 17, 2024
8eb5697
DButils.py: fixed join methods
Jan 24, 2024
028dbf5
moved the bind from Metadata constructor to table creation
Jan 24, 2024
9c54844
DButils.py: fixed assertion error
Jan 25, 2024
4becd0d
DButils.py: fixed all warning messages
Jan 30, 2024
812baa8
undid change so CI will run 2.0
Feb 2, 2024
7a12790
added bind to drop_all and removed self from dbu.engine
Feb 6, 2024
83c4964
casted string with sqlalchemy.sql.text()
Feb 22, 2024
fbe6787
added my name to contributors
Feb 22, 2024
2e1cb80
added bind to create_all
May 20, 2024
bde52aa
removed bind from metadata
May 20, 2024
aca843c
scrubber: fix raw SQL syntax in version_number_check
May 20, 2024
8002ce0
clean_test_db: fix raw SQL syntax in vacuum
May 20, 2024
34a04ab
removed extra parentheses
May 21, 2024
edc8b6a
sqlalchemy.sql was used without it imported
Sep 18, 2024
80c5eab
move the bind from Metadata constructor to table creation (to reflect…
Jan 9, 2025
ac70274
execute no longer taking direct SQL string
Jan 17, 2025
e05685a
adding self to bind argument
Jan 20, 2025
2e4b4b5
imp was discontinued, uptdated to importlib
Feb 7, 2025
9ddd322
Creates error directory if it doesn't exist
Feb 7, 2025
eef7f28
Updating python print syntax to a function call
Feb 7, 2025
30f0e6c
reverting back to imp for Python 2.7
Feb 10, 2025
06d0fc0
imp for multiple python versions
Feb 10, 2025
f9e2230
Update test to handle new Python error message formatting
Mar 10, 2025
4a29c7e
imp updated to importlib for load_source past Python 3.4
Mar 10, 2025
39476ce
Update error message checking to comply with python 3.12 syntax
Mar 11, 2025
e1404c3
Updated error message checking to comply with Python 3.12 syntax
Mar 11, 2025
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 .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
pip install --user python-dateutil
sudo apt update
sudo apt install python3-pip
pip3 install --user "sqlalchemy<2.0"
pip3 install --user sqlalchemy
pip3 install --user python-dateutil
- persist_to_workspace:
root: ~/.local
Expand Down
136 changes: 77 additions & 59 deletions dbprocessing/DButils.py

Large diffs are not rendered by default.

12 changes: 10 additions & 2 deletions dbprocessing/dbprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from __future__ import print_function

import datetime
import imp
import os
import shutil
import sys
Expand Down Expand Up @@ -259,7 +258,16 @@ def figureProduct(self, filename=None):
claimed = []
for code, desc, arg, product in act_insp:
try:
inspect = imp.load_source('inspect', code)
if sys.version_info < (3,4):
import imp # imp is deprecated at python 3.4
inspect = imp.load_source('inspect', code)
else:
import importlib.util # used in python 3.4 and above
import importlib.machinery
loader = importlib.machinery.SourceFileLoader('inspect', code)
spec = importlib.util.spec_from_file_location('inspect', code, loader=loader)
inspect = importlib.util.module_from_spec(spec)
loader.exec_module(inspect)
except IOError as msg:
DBlogging.dblogger.error('Inspector: "{0}" not found: {1}'.format(code, msg))
if os.path.isfile(code + ' '):
Expand Down
1 change: 1 addition & 0 deletions dbprocessing/runMe.py
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,7 @@ def moveToError(self, fname):
DBlogging.dblogger.debug("Entered moveToError: {0}".format(fname))

path = self.dbu.getErrorPath()
os.makedirs(path, exist_ok=True) # Creates error directory if doesn't exist
if os.path.isfile(os.path.join(path, os.path.basename(fname) ) ):
#TODO do I really want to remove old version:?
os.remove( os.path.join(path, os.path.basename(fname) ) )
Expand Down
8 changes: 2 additions & 6 deletions developer/scripts/clean_test_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

import datetime
import dbprocessing.DButils

import sqlalchemy

def find_related_products(dbu, prod_ids, outputs=False):
"""Find all input/output products for a list of products
Expand Down Expand Up @@ -67,7 +67,6 @@ def find_related_products(dbu, prod_ids, outputs=False):
for prod_id in range(1, 190):
if prod_id in keep_products:
continue

files = [rec.file_id for rec in dbu.getFiles(product=prod_id)]
for file_id in files:
dbu._purgeFileFromDB(file_id, trust_id=True, commit=False)
Expand All @@ -76,13 +75,11 @@ def find_related_products(dbu, prod_ids, outputs=False):
.filter_by(product_id=prod_id)
for ll in list(sq):
dbu.session.delete(ll)

sq = dbu.session.query(dbu.Productprocesslink)\
.filter_by(input_product_id=prod_id)
results = list(sq)
for ll in results:
dbu.session.delete(ll)

sq = dbu.session.query(dbu.Process).filter_by(output_product=prod_id)
results = list(sq)
for ll in results:
Expand All @@ -99,7 +96,6 @@ def find_related_products(dbu, prod_ids, outputs=False):
results = list(sq)
for ll in results:
dbu.session.delete(ll)

dbu.delProduct(prod_id) # performs commit

# Only keep a few dates
Expand All @@ -116,5 +112,5 @@ def find_related_products(dbu, prod_ids, outputs=False):
for file_id in delme:
dbu._purgeFileFromDB(file_id, trust_id=True, commit=False)
dbu.commitDB()
dbu.session.execute('VACUUM')
dbu.session.execute(sqlalchemy.sql.text("VACUUM"))
dbu.commitDB()
1 change: 1 addition & 0 deletions docs/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Current developers (*italics denote project administrators*) are:
| Andrew Walker
| Meilin Yan
| Xiaoguang Yang
| Elisabeth Drakatos

Acknowledgements
================
Expand Down
9 changes: 3 additions & 6 deletions examples/scripts/CreateDBsabrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ def init_db(self, user, password, db, host='localhost', port=5432):
url = "postgresql://{0}:{1}@{2}:{3}/{4}"
url = url.format(user, password, host, port, db)
self.engine = create_engine(url, echo=False, encoding='utf-8')
self.metadata = sqlalchemy.MetaData(bind=self.engine)
self.metadata.reflect()
self.metadata = sqlalchemy.MetaData()
self.metadata.reflect(bind=self.engine)

def createDB(self):
"""
Expand Down Expand Up @@ -318,10 +318,7 @@ def createDB(self):
# engine = create_engine('postgres:///' + self.filename, echo=False)
# metadata.bind = engine

metadata.create_all(checkfirst=True)
# self.engine = engine
# self.metadata = metadata

metadata.create_all(checkfirst=True, bind=self.engine)
def addMission(self, filename):
"""utility to add a mission"""
self.dbu = DButils.DButils(filename)
Expand Down
4 changes: 2 additions & 2 deletions functional_test/scripts/run_rot13_L0toL1.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ def doProcess(infiles, outfile):
infiles = sorted(args[:-1])
outfile = args[-1]

print "infiles", infiles
print "outfile", outfile
print("infiles + ", infiles)
print("outfile + ", outfile)
doProcess(infiles, outfile)
9 changes: 5 additions & 4 deletions functional_test/scripts/run_rot13_L1toL2.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#!/usr/bin/env python
import codecs
from optparse import OptionParser

def doProcess(infile, outfile):
with open(outfile, 'w') as output:
with open(infile) as infile:
output.write(infile.read().encode('rot13'))

output.write(codecs.encode(infile.read(), 'rot_13'))
if __name__ == '__main__':
usage = "usage: %prog infile outfile"
parser = OptionParser(usage=usage)
Expand All @@ -18,6 +19,6 @@ def doProcess(infile, outfile):
infile = args[0]
outfile = args[-1]

print "infile", infile
print "outfile", outfile
print("infile + ", infile)
print("outfile + ", outfile)
doProcess(infile, outfile)
2 changes: 1 addition & 1 deletion functional_test/scripts/run_rot13_RUN_timebase.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ def doProcess(infile):

infile = args[0]

print "infile", infile
print("infile + ", infile)
doProcess(infile)
4 changes: 3 additions & 1 deletion scripts/scrubber.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import argparse

import sqlalchemy.sql

from dbprocessing import DButils

class scrubber(object):
Expand All @@ -24,7 +26,7 @@ def parents_are_newest(self):
print(np.difference(n))

def version_number_check(self):
x = self.dbu.session.execute("SELECT max(interface_version), max(quality_version), max(revision_version) FROM file").fetchone()
x = self.dbu.session.execute(sqlalchemy.sql.text("SELECT max(interface_version), max(quality_version), max(revision_version) FROM file")).fetchone()
if x[0] >= 1000:
print("A interface version is too large")
if x[1] >= 1000:
Expand Down
6 changes: 3 additions & 3 deletions unit_tests/dbp_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ def removeTestDB(self):
"""
if self.pg:
self.dbu.session.close()
self.dbu.metadata.drop_all()
self.dbu.metadata.drop_all(bind=self.dbu.engine)
self.dbu.closeDB() # Before the database is removed...
del self.dbu
shutil.rmtree(self.td)
Expand Down Expand Up @@ -282,7 +282,7 @@ def loadData(self, filename):
# persist_selectable added 1.3 (mapped_table deprecated)
tbl = insp.persist_selectable\
if hasattr(insp, 'persist_selectable') else insp.mapped_table
tbl.drop()
tbl.drop(bind=self.dbu.engine)
self.dbu.metadata.remove(tbl)
del self.dbu.Unixtime
if data['productprocesslink']\
Expand All @@ -306,7 +306,7 @@ def loadData(self, filename):
sel = "SELECT pg_catalog.setval(pg_get_serial_sequence("\
"'{table}', '{column}'), {maxid})".format(
table=t, column=idcolumn, maxid=maxid)
self.dbu.session.execute(sel)
self.dbu.session.execute(sqlalchemy.sql.text(sel))
self.dbu.commitDB()
# Re-reference directories since new data loaded
self.dbu.MissionDirectory = self.dbu.getMissionDirectory()
Expand Down
2 changes: 1 addition & 1 deletion unit_tests/test_CreateDB.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def test1(self):
dbu = DButils.DButils(testdb)
if pg:
dbu.session.close()
dbu.metadata.drop_all()
dbu.metadata.drop_all(bind=dbu.engine)
del dbu
finally:
shutil.rmtree(td)
Expand Down
5 changes: 3 additions & 2 deletions unit_tests/test_DBRunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,9 @@ def test_parse_dbrunner_args_bad(self):
finally:
sys.stderr.close()
sys.stderr = oldstderr
self.assertEqual(
'{}: error: {}'.format(os.path.basename(sys.argv[0]), msg), err)
running_script = os.path.basename(sys.argv[0])
self.assertTrue(err.startswith("{}: error: argument".format(running_script)))



class DBRunnerCalcRunmeTests(unittest.TestCase, dbp_testing.AddtoDBMixin):
Expand Down
2 changes: 1 addition & 1 deletion unit_tests/test_DButils.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def tearDown(self):
super(DBUtilsEmptyTests, self).tearDown()
if self.pg:
self.dbu.session.close()
self.dbu.metadata.drop_all()
self.dbu.metadata.drop_all(bind=self.dbu.engine)
self.dbu.closeDB()
del self.dbu
shutil.rmtree(self.td)
Expand Down
45 changes: 35 additions & 10 deletions unit_tests/test_Inspector.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import datetime
import unittest
import tempfile
import imp
import sys
import warnings
import os

Expand Down Expand Up @@ -59,9 +59,17 @@ def setUp(self):
self.makeTestDB()
self.loadData(os.path.join(dbp_testing.testsdir, 'data', 'db_dumps',
'testDB_dump.json'))
self.inspect = imp.load_source('inspect', os.path.join(
dbp_testing.testsdir, 'inspector', 'rot13_L1.py'))

if sys.version_info < (3, 4):
import imp
self.inspect = imp.load_source('inspect', os.path.join(dbp_testing.testsdir, 'inspector', 'rot13_L1.py'))
else:
import importlib.util
import importlib.machinery
loader = importlib.machinery.SourceFileLoader('inspect', os.path.join(dbp_testing.testsdir, 'inspector', 'rot13_L1.py'))
spec = importlib.util.spec_from_file_location('inspect', os.path.join(dbp_testing.testsdir, 'inspector', 'rot13_L1.py'), loader=loader)
self.inspect = importlib.util.module_from_spec(spec)
loader.exec_module(self.inspect)

def tearDown(self):
super(InspectorClass, self).tearDown()
self.removeTestDB()
Expand All @@ -80,10 +88,18 @@ def test_inspector(self):
self.assertEqual(repr(Diskfile.Diskfile(goodfile, self.dbu)), repr(self.inspect.Inspector(goodfile, self.dbu, 1,)()))
#self.assertEqual(None, self.inspect.Inspector(goodfile, self.dbu, 1,).extract_YYYYMMDD())
# This inspector sets the data_level - not allowed
inspect = imp.load_source('inspect', os.path.join(
dbp_testing.testsdir, 'inspector', 'rot13_L1_dlevel.py'))
with warnings.catch_warnings(record=True) as w:
self.assertEqual(repr(Diskfile.Diskfile(goodfile, self.dbu)), repr(self.inspect.Inspector(goodfile, self.dbu, 1,)()))
if sys.version_info < (3, 4):
import imp # Depracated in Python 3.4
inspect = imp.load_source('inspect', os.path.join(dbp_testing.testsdir, 'inspector', 'rot13_L1_dlevel.py'))
else:
import importlib.util
import importlib.machinery
loader = importlib.machinery.SourceFileLoader('inspect', os.path.join(dbp_testing.testsdir, 'inspector', 'rot13_L1_dlevel.py'))
spec = importlib.util.spec_from_file_location('inspect', os.path.join(dbp_testing.testsdir, 'inspector', 'rot13_L1_dlevel.py'), loader=loader)
inspect = importlib.util.module_from_spec(spec)
loader.exec_module(inspect)
with warnings.catch_warnings(record=True) as w:
self.assertEqual(repr(Diskfile.Diskfile(goodfile, self.dbu)), repr(inspect.Inspector(goodfile, self.dbu, 1,)()))
self.assertEqual(len(w), 1)
self.assertTrue(isinstance(w[0].message, UserWarning))
self.assertEqual('Inspector rot13_L1_dlevel.py: set level to 2.0, '
Expand All @@ -93,8 +109,17 @@ def test_inspector(self):
# The file doesn't match the inspector pattern...
badfile = os.path.join(
dbp_testing.testsdir, 'inspector', 'testDB_01_first.raw')
inspect = imp.load_source('inspect', os.path.join(
dbp_testing.testsdir, 'inspector', 'rot13_L1.py'))
if sys.version_info < (3, 4):
import imp # Depracated in Python 3.4
inspect = imp.load_source('inspect', os.path.join(dbp_testing.testsdir, 'inspector', 'rot13_L1.py'))
else:
import importlib.util
import importlib.machinery
loader = importlib.machinery.SourceFileLoader('inspect', os.path.join(dbp_testing.testsdir, 'inspector', 'rot13_L1.py'))
spec = importlib.util.spec_from_file_location('inspect', os.path.join(dbp_testing.testsdir, 'inspector', 'rot13_L1.py'), loader=loader)
inspect = importlib.util.module_from_spec(spec)
loader.exec_module(inspect)

self.assertEqual(None, inspect.Inspector(badfile, self.dbu, 1,)())

def test_inspector_regex(self):
Expand Down
4 changes: 2 additions & 2 deletions unit_tests/test_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def setUp(self):
self.engine = sqlalchemy.create_engine(
'sqlite:///{}'.format(os.path.join(self.td, 'test.sqlite')),
echo=False)
self.metadata = sqlalchemy.schema.MetaData(bind=self.engine)
self.metadata = sqlalchemy.schema.MetaData()

def tearDown(self):
"""Delete test database"""
Expand All @@ -54,7 +54,7 @@ def makeTables(self, *tables):
name: sqlalchemy.schema.Table(
name, self.metadata, *dbprocessing.tables.definition(name))
for name in tables}
self.metadata.create_all()
self.metadata.create_all(bind=self.engine)
actual = sqlalchemy.inspection.inspect(self.engine)\
.get_table_names()
self.assertEqual(sorted(tables), sorted(actual))
Expand Down