简体   繁体   English

ORM 导致的 Flask_SQLAlchemy 模块化问题

[英]Flask_SQLAlchemy modularization issues due ORM

I am trying to build an API using Flask.我正在尝试使用 Flask 构建 API。 For database actions I use flask_sqlalchemy.对于数据库操作,我使用 flask_sqlalchemy。

In my main file, the flask app is initalized.在我的主文件中,烧瓶应用程序已初始化。 I pass the resulting instance to another file where the configuration is set and to my database module that handles database operations.我将生成的实例传递给另一个设置了配置的文件,以及处理数据库操作的数据库模块。

main.py:主要.py:

app = flask.Flask(__name__)  # initialize flask app

#initialize modules with app
config.init(app)
database.init(app)

The problem is, the relations I use in the database are in a seperate file and it needs the db object to declare the classes for ORM.问题是,我在数据库中使用的关系在一个单独的文件中,它需要 db 对象来声明 ORM 的类。

My idea was to declare db and initialize it later in an init function, but that doesn't work in this case, because the db object is undefined when the pythonfile is loaded by an import.我的想法是声明 db 并稍后在 init 函数中对其进行初始化,但这在这种情况下不起作用,因为当导入加载 pythonfile 时 db 对象未定义。

relations.py关系.py

db: SQLAlchemy


def init(db):
    Relations.db = db


class Series(db.Model):
    """Representation of a series
    """
    id = db.Column(db.String(255), primary_key=True)
    title = db.Column(db.String(255))


class User(db.Model):
    """Representation of a user
    """
    id = db.Column(db.INT, primary_key=True)
    name = db.Column(db.String(255))


class Subscription(db.Model):
    """Representation of a subscription
    """

    series_id = db.Column(db.INT, primary_key=True)
    user_id = db.Column(db.String(255), primary_key=True)

My database module uses the way and it works fine( init .py file):我的数据库模块使用这种方式并且工作正常( init .py 文件):

db: SQLAlchemy


def init(app):
    database.db = SQLAlchemy(app)

# handle database operations...

One approach to solve the issue is just using another instance in the relations.py like that:解决该问题的一种方法是在 Relations.py 中使用另一个实例,如下所示:

app = flask.Flask(__name__)
db = SQLAlchemy(app)

# declare classes...

I tried it out and it workes, but that is not a nice way to solve this and leads to other problems.我尝试了它并且它有效,但这不是解决这个问题的好方法并导致其他问题。 Importing it from main does also not work because of circular import.由于循环导入,从 main 导入它也不起作用。

I have no idea how to smoothly solve this without removing modularization.我不知道如何在不删除模块化的情况下顺利解决这个问题。 I would be thankful for any inputs.我会感谢任何投入。 If I should add any further information, just let me know.如果我应该添加任何进一步的信息,请告诉我。

I would create the app variable in your main.py file but leave out the initializing part.我会在你的 main.py 文件中创建 app 变量,但忽略初始化部分。 From there you call a function from init.py to basically set up the database.从那里你从 init.py 调用一个函数来基本设置数据库。 That is what I did for my last flask project.这就是我为我的最后一个烧瓶项目所做的。

Main.py:主要.py:

from init import create_app

app = create_app()

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

Init.py:初始化.py:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
    
db = SQLAlchemy()
DB_NAME = "database.db"
    
    
def create_app():
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
    db.init_app(app)
    
    create_database(app)
    
    #Other operations ... 
    
    return app

Relations.py关系.py

from init import db 

#all your classes ...

db.create_all()

So now you can import the db object to your relations.py file from the init.py.所以现在您可以将 db 对象从 init.py 导入到您的关系.py 文件中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM