0

I have created a db and 2 table schemas in a file called schema.py:

import sqlalchemy as sql
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class ProjGutIndex(Base):
    __tablename__ = 'Project Gutenberg Index'

    id = sql.Column(sql.Integer, primary_key=True)
    title = sql.Column(sql.String)
    link = sql.Column(sql.String)
    description = sql.Column(sql.Text)

    def __repr__(self):
        return "id\t%s | title\t%s | description\t%s" %(self.id, self.title, self.description)

engine = sql.create_engine('sqlite:///../docs/database.db', echo=True)
Base.metadata.create_all(engine)

and I want to then read through a file and commit to that table. But from my understanding I need to import that table class (ProjGutIndex) to be able to do something like (db_load.py):

import sqlalchemy as sql
from sqlalchemy.orm import sessionmaker
import os
from bs4 import BeautifulSoup
import re
from schema import ProjGutIndex

file_wd = os.path.dirname(os.path.realpath(__file__))
relative_path = '/PG_catalogue/PG_catalogue_2020-11-04/cache/epub'
abs_path = file_wd + relative_path
indices = os.listdir(abs_path)

engine = sql.create_engine('sqlite:///../docs/database.db', echo=True)
Session = sessionmaker(bind=engine)

...

session = Session()
        
listed = session.query(ProjGutIndex).filter(ProjGutIndex.title.like(book_title)).first()

if not listed:
    book = ProjGutIndex(title=book_title.strip(), description=book_description.strip()+' '+str(book_cover).strip())
    session.add(book)
    session.commit()
else:
    with open(file_wd+'/../docs/importlog.txt', 'a+') as log:
        f.write(index+' EXISTS,\n')
        
session.close()
...

When I run this, my code fails and says:

...
sqlite3.OperationalError: unable to open database file

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "e:/.../myapplication/db_load.py", line 6, in <module>
    from schema import ProjGutIndex
  File "e:\...\myapplication\schema.py", line 29, in <module>
    Base.metadata.create_all(engine)
...
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) unable to open database file
(Background on this error at: http://sqlalche.me/e/13/e3q8)

The folder structure is:

myapplication/
---- db_load.py
---- schema.py
docs/
---- logfiles.txt
---- database.db

And I'm wondering:

  1. if I'm only importing a class from that module why is it having a problem on the line Base.metadata.create_all(engine). Why is that even running?
  2. does the whole script (schema.py) gets ran every time I import something from it?
  3. and how can I now fix this, if I want to import the class to use it in my db_load.py?
  4. where can I read about filing conventions of applications? I don't know if the way I have structured my folders is silly or not.
Shervin Rad
  • 460
  • 9
  • 21

1 Answers1

1

When you import from another file, it runs the whole file. If there's a part of the file you don't want to be run, put it in an if __name__ == "__main__", like this:

if __name__ == "__main__":
    engine = sql.create_engine('sqlite:///../docs/database.db', echo=True)
    Base.metadata.create_all(engine)
Seth
  • 2,214
  • 1
  • 7
  • 21