0

init.py and models.py are in the same directory (myproject)

myproject
 |
 -- __init__.py
 -- models.py
 |
 app.py

When I try to import something inside models.py from init I get:

ModuleNotFoundError: No module named 'myproject'

What I try:

from myproject import db,login_manager

How can I import something from init (e.g. the database) when it is inside the same directory as the other .py file?

Inside init:

import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager


login_manager = LoginManager()

app = Flask(__name__)

app.config['SECRET_KEY'] = 'mysecretkey'
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + 
os.path.join(basedir, 'data.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)
Migrate(app,db)

login_manager.init_app(app)

login_manager.login_view = "login"

Inside models.py:

from myproject import db,login_manager
from werkzeug.security import 
generate_password_hash,check_password_hash
from flask_login import UserMixin

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(user_id)

class User(db.Model, UserMixin):


    __tablename__ = 'users'


    id = db.Column(db.Integer, primary_key = True)
    email = db.Column(db.String(64), unique=True, index=True)
    username = db.Column(db.String(64), unique=True, index=True)
    password_hash = db.Column(db.String(128))

    def __init__(self, email, username, password):
        self.email = email
        self.username = username
        self.password_hash = generate_password_hash(password)

    def check_password(self,password):

        return check_password_hash(self.password_hash,password)

Inside app.py (where I am exectuing my project from - it also works) just wondering why the import in models.py outputs the error message

from myproject import app,db
from flask import render_template, redirect, request, url_for, 
flash,abort
from flask_login import login_user,login_required,logout_user
from myproject.models import User
from myproject.forms import LoginForm, RegistrationForm
from werkzeug.security import generate_password_hash, 
check_password_hash


@app.route('/')
def home():
    return render_template('home.html')

-- (some more view functions) --





if __name__ == '__main__':
    app.run(debug=True)
  • 1
    may I know what happens if you try just `import db,login_manager` – KcH Oct 16 '19 at 12:01
  • @Codenewbie sure, ModuleNotFoundError: No module named 'db' –  Oct 16 '19 at 12:36
  • so the answer below should actually work..... – KcH Oct 16 '19 at 13:26
  • I am getting ValueError: Attempted relative import in non-package when I try the solution below –  Oct 16 '19 at 13:36
  • 1
    try login_manager after app instance then import as `from . import db, login_manager` and also would you put up app.py too.. – KcH Oct 16 '19 at 13:44

2 Answers2

1

Use the . to import from the same level.

from . import db, login_manager
noslenkwah
  • 1,702
  • 1
  • 17
  • 26
  • 1
    Thanks for replying! I am getting: ValueError: Attempted relative import in non-package when i try your solution –  Oct 16 '19 at 13:35
  • @Raydex - Can you clarify your file structure? This error will be solved by putting an `__init__.py` in the right place (probably in `myproject`) but the diagram in the question looks ambiguous to me so I can't tell you for sure. – noslenkwah Oct 16 '19 at 13:52
  • __init__.py and models.py both are on the same level inside the myproject directory. app.py is at the same level of myproject. so the structure should be correct I think? –  Oct 16 '19 at 15:43
  • 1
    How are you executing this? `python app.py`? If so, can you post `app.py`? – noslenkwah Oct 16 '19 at 15:54
  • 1
    yeah im executing app.py. the strange thing is, is that my script is working totally fine im just confused why I can't run models.py (or get error message when I import from init while being in the same directory). I will post app.py now –  Oct 16 '19 at 16:29
  • If `python app.py` works fine, what are you doing that creates the error? Are you running `python myproject/models.py`? – noslenkwah Oct 16 '19 at 16:54
  • exactly I am just wondering why I get the error when running python/myproject/models.py . The app itself works totally fine (when i run app.py) but I don't get how models.py (and therfore my database - because I defined my db table in there) works if I technically havent importet the database due to that error –  Oct 16 '19 at 18:00
  • sorry if I don't explain it accurately: In app.py I import the class created in models.py which is the table of my database but I am wondering why this works because I can't import the database from __init__ into models.py due to that error –  Oct 16 '19 at 18:21
  • I'm not entirely sure what you are trying to achieve, but it sound a lot like [this](https://stackoverflow.com/questions/582723/how-to-import-classes-defined-in-init-py) question. Check it out. – noslenkwah Oct 16 '19 at 19:23
0

You need to set the PYTHONPATH such that model.py can find myproject module.

If you're running flask shell, try the following inside myproject directory

export PYTHONPATH=.
flask shell

Ref: https://docs.python.org/2/using/cmdline.html#envvar-PYTHONPATH

Sujan Adiga
  • 1,331
  • 1
  • 11
  • 20