-
Notifications
You must be signed in to change notification settings - Fork 4
updated dbprocessing code for sqlalchemy 2.0 #137
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
base: main
Are you sure you want to change the base?
Conversation
jtniehof
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Functionality looks good. Just to make history less arduous, can you do some rebasing and squash some commits together?
- the four commits, three "added bind to drop_all" and "removed self from dbu_engine" should be one
- "fixed warning message" and "fixed all warning messages" should be one
- the "added bind=self.engine" and "took out bind=self.engine" should be combined; really this is "move the bind from Metadata constructor to table creation"
- probably the two "fixed another join" should be one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did a few quick checks for places which aren't in the unit tests but show a similar pattern to what we had to change.
create_all requiring the bind now: CreateDBsabrs line 321 (@dnadeau-lanl , is CreateDBsabrs now out of date, or is it superseded now that we can create postgres databases? Maybe we should be removing it instead.)
execute no longer taking a direct SQL string: scrubber line 27, clean_test_db line 119. To test the scrubber, we're actually kind of short on canned test databases (the psp one is enormous now). You can get an old one from history by git show e3c67f3feabdc62bec2ffabba78bceb3d8dd5d89:./functional_test/testDB.sqlite > foo.sqlite. You can get the old mageis database for testing clean_test_db with git show 18469404b10ece57051b9b2391c1ea3c0741aefe:./unit_tests/RBSP_MAGEIS.sqlite > RBSP_MAGEIS.sqlite
MetaData no longer taking a bind argument (having to bind separately): CreateDBsabrs line 40 (like in other places where we've made that change, that line needs to be fixed and specifying the bind may have to happen in multiple places) EDIT: bind needs to be added to the reflect call in init_db (right after it was removed from the instantiation of self.metadata, and somewhat related the create_all call around line 321 already has the bind, but should be self.engine not engine.
The functional test is also not running. Unfortunately it doesn't run in the CI (#68) so it's possible this has just drifted out of date. Running it is pretty simple, run python ./functionalTest.py in the functional_test directory. Unfortunately debugging it is going to be harder; it makes a temp directory where all the scripts and such live, and for some reason when the codes fail to run, the moveToError that copies the error log to the error directory is also failing.
For finding these various scripts, use find in the dbprocessing checkout.
dfe33cc to
34a04ab
Compare
f7ef949 to
66df48d
Compare
77c64fb to
e5c4e55
Compare
jtniehof
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few fairly minor changes suggested
| print "infiles", infiles | ||
| print "outfile", outfile | ||
| print("infiles + ", infiles) | ||
| print("outfile + ", outfile) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The plus should be outside the quote here, since it's concatanation...this will put in an extra comma and parens.
| output.write(infile.read().encode('rot13')) | ||
|
|
||
| output.write(codecs.encode(infile.read(), 'rot_13')) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extra whitespace here
| print "infile", infile | ||
| print "outfile", outfile | ||
| print("infile + ", infile) | ||
| print("outfile + ", outfile) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as for the L0 to L1 (concatenate, not print a literal +)
| infile = args[0] | ||
|
|
||
| print "infile", infile | ||
| print("infile + ", infile) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
unit_tests/test_Inspector.py
Outdated
| 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,)())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we break this out into a function, or static method, that gets called both here and the setup? Or I wonder about putting the function in dbprocessing/Utils.py, since this is also used by the code in dbprocessing/dbprocessing.py.
dbprocessing/dbprocessing.py
Outdated
| 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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is used in several places, see comments below.
I'm always wary of explicit self.version_info checks and would prefer we check, say, if importlib.util exists. However, the very next thing we're going to do is rip out support for old versions of Python, so I'm inclined to leave this as you wrote it.
jtniehof
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small stuff, can probably just do a single cleanup commit and call it good.
| else: | ||
| ans[section][item] = (ans[section][item], 0, 0) | ||
| return ans | ||
| def load_source(modname, filepath, module): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PEP8 specifies space (i.e. one empty line) between the functions.
Can you document parameters/returns as in the other functions?
The module argument doesn't appear to be used--can it be removed? (And then update calls to it, of course).
| for code, desc, arg, product in act_insp: | ||
| try: | ||
| inspect = imp.load_source('inspect', code) | ||
| fname = code |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this assignment necessary? Can't we just pass "code" directly to load_source?
| inspect = imp.load_source('inspect', code) | ||
| fname = code | ||
| inspect = None | ||
| inspect = Utils.load_source('inspect',fname, inspect) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
space after the comma per PEP-8
| output.write(infile.read().encode('rot13')) | ||
|
|
||
| output.write(codecs.encode(infile.read(), 'rot_13')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
go ahead and retain the empty line at the end of the function
| 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))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per PEP 8, keep two blank lines after the class definition
| dbp_testing.testsdir, 'inspector', 'rot13_L1.py')) | ||
|
|
||
| filename = os.path.join(dbp_testing.testsdir, 'inspector', 'rot13_L1.py') | ||
| self.inspect = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you update load_source not to take the module argument, all these None assignments can go away (several in this file)
| def test_load_source(self): | ||
| """Testing load_source in Utils.py""" | ||
| filename = "temp_testfile.py" | ||
| with open(filename, "w") as f: | ||
| f.write("def hello():\n return 'Hello, world!'\n") | ||
| inspect = None | ||
| module = Utils.load_source("temp_testfile", filename, inspect) | ||
| self.assertEqual(module.hello(), 'Hello, world!') | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice test. Do leave a blank line before it, and two after (because it's the end of the class). Use tempfile to make a temporary directory and put your test file in there, then clean it up after (with a try/finally)--that way you're not leaving it in the current directory.
Updated a series of errors so that dbprocessing code works for both sqlalchemy 2.0 and sqlalchemy 1.4. Closes #135.
Adding/Removing bind=self.engine
Join syntax needs to be reorganized so that the order of the second argument aligns with the first argument, as well as deleting extra parenthesis
Replaced Query.get() with Session.get()
PR Checklist
Closes #if this PR closes the issue, or some other reference, such as See # if it is related in some other way)*We don't yet have unit tests to make sure warnings aren't raised, the tests now pass without warnings on Python 3.10, sqlalchemy 1.4, and 2.0.