简体   繁体   English

(烧瓶)-sqlalchemy查询,必须导入所有模型

[英](flask)-sqlalchemy query, have to import all models

I have a problem with Flask and Flask-SQLAlchemy where for any query I would need to import all the related models. 我在Flask和Flask-SQLAlchemy上遇到问题,对于任何查询,我都需要导入所有相关模型。

Now my auth.views.py looks like this (first few lines of programming this thing so just a test view) 现在我的auth.views.py看起来像这样(对这件事进行编程的前几行只是一个测试视图)

from flask import jsonify                                                   

from . import auth                                                          
from app.models.user import User                                            


@auth.route('/', methods=['GET'])                                            
def index():                                                                 
    users = User.query.all()                                                     
    return jsonify({'name': users[0].name}) 

Now I'm getting an error 现在我遇到一个错误

"InvalidRequestError: When initializing mapper Mapper|User|user, expression 'Course' failed to locate a name ("name 'Course' is not defined"). If this is a class name, consider adding this relationship() to the class after both dependent classes have been defined." “ InvalidRequestError:初始化映射器Mapper | User | user时,表达式'Course'无法找到名称(“ name'Course'未定义”。)如果这是一个类名,请考虑在该类之后添加此Relationship()两个相关的类都已定义。”

I have a project where i have a models package like so 我有一个项目,其中有一个像这样的模型包

app                                                                         
├── auth                                                                    
│   ├── __init__.py                                                         
│   └── views.py                                                            
├── __init__.py                                                             
└── models                                                                  
    ├── assignment.py                                                       
    ├── base.py                                                             
    ├── client.py                                                           
    ├── course.py                                                           
    ├── __init__.py                                                         
    ├── submission.py                                                       
    └── user.py    

my user class has a many to many with Course and a one to many with Submission. 我的用户类与课程有很多对比,与提交有一对多。

This is solved by importing the Course (and then Submission, and then the relations from there, eventually all the models basically.) 这可以通过导入“课程”(然后是“提交”,然后是从那里的关系,最终是所有模型)来解决。

At work for Pyramid projects we also work with SQLAlchemy but I never have to import all the models to do my work. 在为Pyramid项目工作时,我们还使用SQLAlchemy,但我不必导入所有模型即可完成工作。 Any ideas whats up? 有什么想法吗? I really can't figure this out and I haven't been able to google it. 我真的无法弄清楚,也无法用Google搜索。

User looks like this 用户看起来像这样

user_course = db.Table(                                                     
    'user_course', db.Model.metadata,                                          
    db.Column('student_id', UUID, db.ForeignKey('user.id'),                    
              primary_key=True),                                               
    db.Column('course_id', UUID, db.ForeignKey('course.id'),                   
              primary_key=True)                                                
)                                                                              


class User(db.Model):                                                          
    id = db.Column(UUID, default=lambda: str(uuid.uuid4()), primary_key=True) 
    firstname = db.Column(db.String(100), nullable=False)                      
    lastname = db.Column(db.String(100), nullable=False)                       
    insertion = db.Column(db.String(15))  # tussenvoegsel                      
    # email = db.Column(db.String, nullable=False, unique=True)                
    password_hash = db.Column(db.String, nullable=False)                       

    enrolled_courses = db.relationship('Course', secondary=user_course,        
                                       backref='students')                     
    managed_courses = db.relationship('Course', backref='teacher')             

    submissions = db.relationship('Submission', backref='student')             

    @property                                                                  
    def name(self):                                                            
        return "{}{}{}".format(                                                
            self.firstname + " ",                                              
            self.insertion + " " if self.insertion else "",                    
            self.lastname                                                      
        )                                                                      

    @property                                                                  
    def password(self):                                                        
        raise AttributeError("Password is not a readable attribute")           

    @password.setter                                                           
    def password(self, password):                                              
        self.password_hash = bcrypt.hashpw(password, bcrypt.gensalt(12))       

    def verify_password(self, password):                                       
        return bcrypt.hashpw(password, self.password_hash) == \                
            self.password_hash    

If you really want to stick to the one-file-per-class scheme, in my opionion, the cleaner option would be to do the imports in the model package's init: 如果您真的想坚持每类一个文件的方案,在我看来,更干净的选择是在模型包的init中进行导入:

models/__init__.py:

from user import User
from client import Client
from course import Course
# plus your remaining classes

Then you can import the classes as 然后您可以将类导入为

from models import User

which makes things more readable and would allow to mix the one-file-per-class scheme with modules containing multiple classes, while still being able to import all classes in a "flat" manner from models . 这使事情更具可读性,并且允许将“每个文件一个文件”方案与包含多个类的模块混合使用,同时仍然能够以“固定”方式从models导入所有类。

Ok so apparantly you can't get around loading all the modules. 好的,如此看来,您无法解决所有模块的加载问题。 I didn't want to do this manually so I resorted to this in __init__.py . 我不想手动执行此操作,因此我在__init__.py求助于此。 Now all the modules will be executed like the comment said needed to happen. 现在,所有模块都将像需要执行的注释一样执行。

import inspect                                                              
import pkgutil                                                                 
import importlib                                                               
import sys                                                                     


def import_models():                                                           
    thismodule = sys.modules[__name__]                                         

    for loader, module_name, is_pkg in pkgutil.iter_modules(                   
            thismodule.__path__, thismodule.__name__ + '.'):                   
        module = importlib.import_module(module_name, loader.path)             
        for name, _object in inspect.getmembers(module, inspect.isclass):      
            globals()[name] = _object                                                                                     

import_models()        

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

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