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

2024 _47b; Add db models #4

Open
wants to merge 13 commits into
base: dev
Choose a base branch
from
Open

Conversation

kami-nashi
Copy link
Contributor

@kami-nashi kami-nashi commented Nov 22, 2024

With the basic changes, I'm able to import ice_time.py into a file and build a query that returns expected data.

from models import ice_time as time

ashley = time(1).ice_time_in_minutes()
inara = time(2).ice_time_in_minutes()

print(ashley, inara)

python scratch.py -> 45 285

If this file structure and class structure is sensible, the remaining queries will be added from legacy skatetrax to this commit.

@kami-nashi kami-nashi linked an issue Nov 22, 2024 that may be closed by this pull request
@kami-nashi kami-nashi marked this pull request as ready for review November 28, 2024 01:25
@kami-nashi
Copy link
Contributor Author

This should now satisfy the items in #2.


class add():

def boot(boots):
Copy link

Choose a reason for hiding this comment

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

Class methods will have the first argument as self. Is this what you want?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have to admit, I'm not sure about this, and in a few ways. Ive been able to use this code to insert rows as expected..... so self being the first arg doesnt seem to affect anything... How ever, I'm not sure how/why that makes an impact here because Im lacking the understanding behind why this is the behavior.

Ultimately, i want to structure things in a way that i can import models, which may actually be the wrong verbiage now that i think about it, and do something like...

from models import equipment as equip

equip.add.boots(some_dict) # add some new boots
equip.table.boots(uSkaterUUID) # dump all rows of previous boots

Perhaps there is a better way of doing that instead of using classes to structure this??

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I do reference the organization/structure a little bit more in #5

# to create, run: python -m models.setup_db

# this script is a complete mess. PEP8 complains about the imports, which are all over the place.
# note sure how to address this, if you're reading this - I sincerely wish it was better. :)
Copy link

Choose a reason for hiding this comment

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

Is PEP8 complaining about imports that are never used in your code?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, and via the documentation and verifying that I'm doing this as expected, the imports have to be after the import for "Base"

date_end = Column(DateTime)
uSkaterUUID = Column(Integer)

def __init__(
Copy link

Choose a reason for hiding this comment

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

Not sure why you put each argument on a separate line. It wastes vertical space. Any particular reason?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Only because they're usually long to put on one line, and when I break them up its much easier for my eyes to stack them vertically.

@@ -0,0 +1,279 @@
# coding=utf-8
import pandas as pd
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I may not be leaving pandas in this unless it brings a very specific advantage or feature. there are some test/learning functions towards the bottom of this file where i'm pulling joined table data directly to build some dataframes, but its unlikely to provide enough advantage to keep the library.


session = Session()


Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've created a separate issue, #5 to consider how to go about structuring this file and the classes within it. Its very unlikely that the final product will resemble the current state since most of these statements were used to verify table and code structure while learning.

There are many opportunities for improvement here.

Ice_Time.uSkaterUUID == self.uSkaterUUID
).where(
Ice_Time.uSkaterConfig == uSkaterConfig
).scalar()
Copy link

Choose a reason for hiding this comment

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

The indentation is strong here. Try to keep a vertical flow.

db_url = os.environ['pgdb_host']
db_name = os.environ['pgdb_name']
db_user = os.environ['pgdb_user']
passwd = os.environ['pgdb_password']
Copy link

Choose a reason for hiding this comment

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

Beware of KeyErrors. You can use .get() with a default value instead of direct subscript with [].

In the case of requiring certain config variables, it would be good to check if they exist, and report back a proper error.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a really good point. I got so tied up in all of the new stuff that I completely forgot to go back and do basic error handling here.

coach_Fname = Column(String)
coach_Lname = Column(String)
coach_rate = Column(Float)
uSkaterUUID = Column(Integer)
Copy link

Choose a reason for hiding this comment

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

Snake_case is usually preferred instead of camelCase, for variable/field names.

self.uSkaterUUID = uSkaterUUID


class events_competition():
Copy link

Choose a reason for hiding this comment

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

CameCase, with first character uppercased, is preferred for class names. Suggestions here: EventsCompetition.

def __init__(self, uSkateUUID):
self.uSkateUUID = uSkateUUID

def ice_cost(self):
Copy link

Choose a reason for hiding this comment

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

If one method is expected and no state is required, then a class is not needed, and a function is preferred.

Suggestion here: def ice_cost(uSkateUUID)

from models.cyberconnect2 import Session
from models.ice_time import Ice_Time

session = Session()
Copy link

Choose a reason for hiding this comment

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

Ideally, creating any states, like a session here, should be done during main runtime. Meaning, that it should be created once it would be used. If this module (and it's submodules) would be imported, a session would be initialized as side-effect. This can create some unexpected behaviors, or confusion, for those wanting to use it as a library. Another strong point, for moving the state creation (initialization) to consumer (main runtime) is testability. Otherwise, creation of tests would require a monkey-patching.

This is just a thought and a general recommendation. There are a usual breakers of this, like creation of a module logger.

@@ -0,0 +1,38 @@
# coding=utf-8
Copy link

Choose a reason for hiding this comment

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

__init__.py should not contain code, but rather just imports (if needed). If submodules are not expected, then this can be a one file, a module, named modules.py.

for coach in coaches:
session.add(Coaches(**coach))
session.commit()
session.close()
Copy link

Choose a reason for hiding this comment

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

A session is prematurely and unexpectedly closed here. Consider utilizing context-manager(with Session(...) as session), or pass the session (db connection) to the class/function.

def add_coaches(coaches):
for coach in coaches:
session.add(Coaches(**coach))
session.commit()
Copy link

Choose a reason for hiding this comment

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

Consider using transactions, and commit after all required records are written.

Committing here would insert one record (Coaches) one by one, likely waiting the db to write it on disk before going to write another record (in the for loop).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Initialize a DB with default tables.
3 participants