SQL alchemy split project into different files - import

I am implementing simple database, right now my goal is to split project into different modules, as it should be done. So far, my project consists of bunch of files:
base.py
from sqlalchemy.orm import declarative_base
Base = declarative_base()
file implementing tables
classes.py
from sqlalchemy import Column, Integer, String, Date, ForeignKey
from sqlalchemy.orm import relationship, validates
from base import Base
class Book(Base):
...
class Owner(Base):
...
creation of engine, session, etc
database.py
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
from datetime import date
from base import Base
engine = create_engine("sqlite+pysqlite:///mydb.db")
session = Session(engine)
from operations import *
import parser_file
Base.metadata.create_all(engine)
if __name__ == '__main__':
parser_file.main()
Here I import session from database.py
operations.py
from classes import Book, Owner
from database import session
def add_book(title, author, year_published=None):
...
# and many more
parser_file.py
import argparse
from datetime import date
from operations import *
def main():
...
I am not sure about the imports. operations.py, parser_file.py and database.py all import from each other. It used to throw error, but i moved from operations import * and import parser_file after creation of Session. It feels sketchy having imports in the middle of the code as I am used to imports on top of file, and on some posts there are people mentioning that modules should not depend on each other. On the other hand, the code is now nicely split and it feels better this way. What is the correct way to handle these?
Edit: From PEP8 guide on imports
Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants
So it seems like what I did is considered bad.

Related

How to import/reference multiple pytest fixtures without wildcard import?

Currently I use the following setup to import pytest fixtures from a file called fixtures.py and run tests with them:
from django.contrib.auth.models import User, Group
from django.core import mail
from main.tests.fixtures import user_a, group_dropoff_for_qc
def test_should_check_password(db, user_a: User) -> None:
user_a.set_password("secret")
assert user_a.check_password("secret") is True
# more tests here
As I write more tests and use more fixtures, that import list from main.tests.fixtures grows really long. Is there some built-in pytest way around this? This seems like such a common operation that there should be a more streamlined approach.
Found the answer on my own, so here is the solution in case this helps anyone else.
Solution source: https://www.tutorialspoint.com/pytest/pytest_conftest_py.htm
If you rename an exterior file that contains fixtures to conftest.py, you can reference the fixtures in that file without needing to explicitly import them. So in my case above, I just had to rename my fixtures.py to conftest.py, which allowed me to run the tests as expected, without the import statement:
from django.contrib.auth.models import User, Group
from django.core import mail
def test_should_check_password(db, user_a: User) -> None:
user_a.set_password("secret")
assert user_a.check_password("secret") is True
# more code here

How to Import from Module in Parent Directory (Python)

I have the file structure:
directory_1/
file_1.py
directory_2/
directory_3/
file_2.py
How can I import a function from file_1 into file_2?
Other answers have led me to try from ...file_1 import fun, after adding an __init__.py file to directory_1, but doing this gives me ValueError: attempted relative import beyond top-level package. I have also tried from directory_1.file_1 import fun but this has given me a ModuleNotFound error.
If anybody could help I would be very grateful!
Solution
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")))
from file_1 import fun
fun()
Umm?
This solution is messy but the only way to avoid it is by restructuring you project, having a look at this might help.

Why am I importing so many classes?

I'm looking at example Spark code and I'm a bit confused as to why the sample code I'm looking at requires two import statements:
import org.apache.spark._
import org.apache.spark.SparkContext._
This is Scala. As I understand it, _ is the wildcard character. So this looks like I'm importing SparkContext twice. Can anybody shed light on this?
This first line says to import all of the classes in the package org.apache.spark. This means you can use all of those classes without prefixing them with the package name.
The second line says to import all of the static members of the class SparkContext. This means you can use those members without prefixing their names with the class name.
Remember import doesn't really do anything at run time; it just lets you write less code. You aren't actually "importing" anything twice. The use of the term import comes from Java, and admittedly it is confusing.
This might help:
Without the first line, you would have to say
org.apache.spark.SparkContext
but the first import line lets you say
SparkContext
If you had only the first line and not the second, you would have to write
SparkContext.getOrCreate
but with both import lines you can just write
getOrCreate

Cats: how to find the specific type from implicits

I have this code which compiles and works fine
import cats.implicits._
Cartesian[ValidResponse].product(
getName(map).toValidated,
readAge(map).toValidated
).map(User.tupled)
However I don't like the import of cats.implicits._ because there is just too many classes there. I tried importing specific things related to Cartesians like
import cats.implicits.catsSyntaxCartesian
import cats.implicits.catsSyntaxUCartesian
import cats.implicits.catsSyntaxTuple2Cartesian
But these did not work. As a newbie I find the implicit imports very confusing because there are simply 1000s of them and the names are not very obvious. My only alternative is to import the entire universe by import cats.implicits._ and stop thinking about it.
In fact I have a broader confusion about cats.implicits, cats.instances._ and cats.syntax._. So far I am just importing these via trial and error. I am not really sure of when to import what.
Do not try to pick out specific things from cats.implicits. You either import the entire thing, or you don't use it at all. Further, there's no reason to be afraid of importing it all. It can't interfere with anything.
Ok, I lied. It will interfere if you import cats.instances.<x>._ and/or cats.syntax.<x>._ alongside cats.implicits._. These groups are meant to be mutually exclusive: you either import everything and forget about it with cats.implicits._, or you specifically select what you want to import with cats.instances and cats.syntax.
These two packages are not meant to be imported completely like cats.implicits. Instead, they include a bunch of objects. Each object contains some implicit instances/syntax, and you are meant to import from those.
import cats.implicits._ // Good, nothing to fear
// RESET IMPORTS
import cats.implicits.catsSyntaxCartesian // Bad, don't pick and choose
// RESET IMPORTS
import cats.instances._ // Bad, is useless
import cats.syntax._ // Ditto
// RESET IMPORTS
import cats.instances.list._ // ok
import cats.syntax.cartesian._ // ok
// RESET IMPORTS
import cats.implicits._
import cats.syntax.monad._ // Bad, don't mix these two
Additionally each of cats.{ instances, syntax } contains an all object, with the obvious function. The import cats.implicits._ is really a shortcut for import cats.syntax.all._, cats.instances.all._.
I'll start by saying that import cats.implicits._ is safe, reasonable and the recommended approach when starting. So if the only reason for this question is that you don't like importing too many classes, then I think you should just bite the bulled at leave that as is.
Additionally, I recommend you take a look at the official cats import guide. It tries to explain the package/logical structure of cats code and might make it easier to understand.
The "cats" library is organized in several "areas" that can be easily distinguished by their package name:
cats._ - This is where most of the typeclasses live (e.g. Monad, Foldable etc.)
cats.data._ - This is the home of data structures like Validated and State.
cats.instances._ - This is where the instances for the typeclasses defined in 1 are. For example if you import cats.instances.list._ you'll bring into scope the Show, Monad etc. instances for the standard List. This is what you're most likely interested in.
cats.syntax._ - has some syntax enrichment that makes code easier to write and read.
An example of ussing cats.syntax._ would be:
import cats.Applicative
import cats.syntax.applicative._
val listOfInt = 5.pure[List]
//instead of
val otherList = Applicative[List[Int]].pure(5)

alphabetically sorted imports

I have
import scala.slick.jdbc.{GetResult, StaticQuery}
import scala.slick.jdbc.StaticQuery.interpolation
this can be shortened to
import scala.slick.jdbc.{GetResult, StaticQuery}
import StaticQuery.interpolation
but then it's no longer sorted alphabetically
This would be nice, but does not work, any alternatives?
import scala.slick.jdbc.{GetResult, StaticQuery, StaticQuery.interpolation}
You can do
import scala.slick.jdbc.{GetResult, StaticQuery}, StaticQuery.interpolation
But that leads to confusing block imports, which also increases the probability for merge errors when you work with other developers. Therefore you should always use absolute imports at the beginning of a file and use relative imports only inside of narrower scopes (like the body of defs).