-
Notifications
You must be signed in to change notification settings - Fork 0
draft #1
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?
draft #1
Conversation
README.md
Outdated
|
|
||
| To query the `EMP` table for all records: | ||
|
|
||
| result = db.execute_query("select * from emp") |
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.
Wrap code examples in ticks.
I'd also like to see a super streamlined example of it put together like:
from pydb import OracleDb
from pylog import logger
db = OracleDb(host="valid_host", port=8003, service="SERVICE_NAME", user="username", pwd="pwd")
result = db.execute_query("select * from emp")
logger.info(json.dumps(result))
db.cleanup()
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.
code wrapped; integrated example added
ccurreri
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.
See the individual comments. Some small design things that seems strange to me, but might make sense in your context. I only commented on the first instances that I saw but some of them are done multiple times.
Chiefly, you have a helper method that gets the connection pool but also expose it as a public attribute. You may want to consider refactoring to make it more clear that there is only one way that folks should be interacting with the pool object.
pydb/database.py
Outdated
| class DBInterface(metaclass=abc.ABCMeta): | ||
| @classmethod | ||
| def __subclasshook__(cls, subclass): | ||
| return (hasattr(subclass, 'execute_query') and | ||
| callable(subclass.execute_query) and | ||
| hasattr(subclass, 'execute_update') and | ||
| callable(subclass.execute_update) and | ||
| hasattr(subclass, 'health_check') and | ||
| callable(subclass.health_check) and | ||
| hasattr(subclass, 'cleanup') and | ||
| callable(subclass.cleanup) and | ||
| hasattr(subclass, 'create_connection') and | ||
| callable(subclass.create_connection) and | ||
| hasattr(subclass, 'get_session') and | ||
| callable(subclass.get_session) | ||
| or NotImplemented) |
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 there a specific reason you're overriding this?
You already are handling this with the abstractmethod decorators. If a subclass fails to implement one of these it can't be instantiated.
>>> from abc import ABC, abstractmethod
>>>
>>> class Foo(ABC):
... @abstractmethod
... def bar(self):
... pass
...
>>> class Baz(Foo):
... pass
...
>>> x = Baz()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Baz with abstract method bar
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.
updated - removed
pydb/oracle_db.py
Outdated
| if self.pool: | ||
| return self.pool | ||
| else: | ||
| self.set_up_session_pool() |
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 else clause here technically will never fire because you always set self.pool in __init__ or throw an error.
One alternative would be to just use a property for this to load it on demand:
class OracleDB(DBInterface):
def __init__(self, host: str, port: int, service: str, user: str, pwd: str,
logging_level: int = 50, logging_format: logging.Formatter = None):
. . .
self._pool = None
. . .
@property
def pool(self):
if not self._pool:
self._pool = self.set_up_session_pool()
return self._pool
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.
updated
pydb/oracle_db.py
Outdated
| connection = self.get_session_pool().acquire() | ||
| return connection |
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.
Could just be:
return self.get_session_pool().acquire()
or with the changes above just:
return self.pool.acquire()
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.
updated
|
|
||
| def create_row(*args): | ||
| return dict(zip(column_names, args)) | ||
| return create_row |
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.
Do you mean return create_row() here or do you actually mean to return the function?
If the latter this is something a lambda could do relatively easily:
return lambda *args: dict(zip(column_names, args))
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 'inherited' this syntax - and am opting to leave as is since it is working as expected
The idea here is to provide a pluggable collection of utils to enable easy interactions with databases of various types.
I've started with oracle db bc the example project into which this package is integrated (a flask api example project) uses an oracle db, but the intent is to enable additional modules for mysql, postgres, etc.
I've updated the documentation in a way that I think makes sense - I was able to start a python console session and follow those instructions (with valid connection information) and pull back results. Please let me know what else might be helpful. One section to be added at beginning: 'Purpose and Intended Audience'