Mark
Mark

Reputation: 169

Can't find __main__ when initializing my SQLite database

I'm new to Python and even newer to Flask. When I'm trying to initialize my database using SQLAlchemy I get an error. Does anyone know what's going on and how I can resolve this issue so I can run db.create_table() to initialize my database and to test my API endpoints?

I enter:

python3
from app import db

The error:

* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
/Users/mark/Documents/Coding/friend_code/venv/bin/python3: can't find '__main__' module in '/Users/mark/Documents/Coding/friend_code'

And this is my entire code inside app.py

import os
import secrets
from flask_sqlalchemy import SQLAlchemy
from flask import Flask, request, jsonify
from flask_marshmallow import Marshmallow

users = []
theme = [
    {'neon red and neon blue': ('rgb(255, 60, 40)', 'rgb(10, 185, 230)')},
    {'gray': ('rgb(130, 130, 130)', 'rgb(130, 130, 130)')},
    {'blue and neon yellow': ('rgb(70, 85, 230)', 'rgb(230, 255, 0)')},
    {'neon pink and neon green': ('rgb(255, 50, 120)', 'rgb(30, 220, 0)')},
    {'neon purple and neon orange': ('rgb(180, 0, 245)', 'rgb(250, 160, 5)')},
    {'neon yellow': ('rgb(250, 160, 5)', 'rgb(250, 160, 5)')}
]

app = Flask(__name__)
basedir = os.path.abspath(os.path.dirname(__file__))

# database
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + \
    os.path.join(basedir, 'db.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# initializion
db = SQLAlchemy(app)
ma = Marshmallow(app)


# user class/model
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True, nullable=False)
    avatar = db.Column(db.String, default='default.jpg', nullable=False,)
    friend_code = db.Column(db.Integer, nullable=False)
    update_code = db.Column(db.String, nullable=False)
    theme = db.Column(db.String, default='neon red and neon blue')
    dark_mode = db.Column(db.Boolean, default=True, nullable=False)

    def __init__(self, username, avatar, friend_code, update_code, theme, dark_mode):
        self.username = username
        self.avatar = avatar
        self.friend_code = friend_code
        self.update_code = update_code
        self.theme = theme
        self.dark_mode = dark_mode


# user schema
class UserSchema(ma.Schema):
    # allowed visible fields
    class Meta:
        fields = ('username', 'avatar', 'friend_code',
                  'update_code', 'theme', 'dark_mode')


# initialization
user_schema = UserSchema()

# GET
@app.route('/<username>', methods=['GET'])
def get(username):
    user = User.query.get(username)
    return user_schema.jsonify(user)

# POST
@app.route('/', methods=['POST'])
def post():
    username = request.json['username']
    avatar = request.json['avatar']
    friend_code = request.json['friend_code']
    update_code = secrets.token_urlsafe(8)
    theme = request.json['theme']
    dark_mode = request.json['dark_mode']

    new_user = User(username, avatar, friend_code,
                    update_code, theme, dark_mode)

    # add to db
    db.session.add(new_user)
    db.session.commit()

    return user_schema.jsonify(new_user)


# run server
app.run(debug=True)

Upvotes: 0

Views: 264

Answers (1)

chuckles
chuckles

Reputation: 761

How are you invoking your code? If you are calling directly, like with

$ python app.py

then you need to wrap the app.run() command inside of a main block at the end of app.py

if __name__ == "__main__":
    app.run(debug=True)

Otherwise if you are trying to invoke the package directly, like with

$ python -m friend_code

then you need to include a __main__.py file inside the folder which contains the block of code with the main block (as well as with the import statement for app).

The issue is that your run server function call is being executed every time you try to import the database from that file, because it is not wrapped with one of these main blocks.

You can read more about how this works from this in-depth answer.

With regard to creating your database tables the simplest method would be creating a file which handles this for you, which you can then run directly

create_db.py

if __name__ == "__main__":
    from app import db
    db.create_all()
    print("Database Created")

Upvotes: 2

Related Questions