如何使用字符串变量作为表名进行 sqlalchemy 查询?

cle*_*e21 6 python-3.x flask-sqlalchemy

如果我不清楚,我提前道歉,英语不是我的母语。如果我犯了太多错误,请随时告诉我:)

我是使用flask_sqlalchemy的新手,在互联网上花费数小时寻找答案后感到沮丧。

我想要的是做一个这样的查询:

ModelName.query.filter_by(name='something').all()
Run Code Online (Sandbox Code Playgroud)

但不是使用 ModelName 我想做这样的事情:

model_list = ['Model1', 'Model2', 'Model3']
for model in model_list:
    some_var = model.query.filter_by(name='something').all()
    # do some stuff with the variable
Run Code Online (Sandbox Code Playgroud)

错误是:

'str' object has no attribute 'query'
Run Code Online (Sandbox Code Playgroud)

在尝试将 db.session.add() 与字符串变量一起使用时,我当然遇到了同样的问题。

我知道查询需要某种 _BoundDeclarativeMeta 对象而不是字符串,但是如何从列表中获取该对象以将其传递给 for 循环?

我尝试使用 'db.metadata.tables[my_variable]' 但我得到了一个 Table 对象而不是一个 _BoundDeclarativeMeta 对象,它的工作方式不一样。

我设法使用

db.session.query(db.metadata.tables[my_variable])
Run Code Online (Sandbox Code Playgroud)

代替

my_variable.query
Run Code Online (Sandbox Code Playgroud)

但我不能将这种方法用于“db.session.add()”(或者有可能吗?)

有什么方法可以将字符串变量“转换”为正确类型的 sqlalchemy 对象?

小智 5

我需要一种通过引用模型的表名进行查询的方法。这就是我想出的:

class Model1(db.Model):
    __tablename__ = 'table1' # or whatever, doesn't matter

class Model2(db.Model):
    __tablename__ = 'table2'

tables_dict = {table.__tablename__: table for table in db.Model.__subclasses__()}

def table_object(table_name):
    return tables_dict.get(table_name)
Run Code Online (Sandbox Code Playgroud)

然后,像这样使用它:

model_list = ['table1', 'table2']
for model in model_list:
    some_var = db.session.query(table_object(table_name=model)).filter_by(name='something').all()
Run Code Online (Sandbox Code Playgroud)

重要的一点是db.Model.__subclasses__()- 给出模型类(对象?)的列表。


ich*_*lau 1

importlib如果您使用的是 python > 2.7,我认为可能会对您有所帮助

importlib.import_module('module to import')
Run Code Online (Sandbox Code Playgroud)

对于您的情况:如果您的项目结构如下所示,并且 models.py 定义了所有 OR 映射类。

a
|
+ - __init__.py
  - b
    |
    + - __init__.py
      - models.py
Run Code Online (Sandbox Code Playgroud)

代码应该是这样的:

model_list = ['Model1', 'Model2', 'Model3']
the_module  = importlib.import_module('module to import') # eg. importlib.import_module('a.b.models')
for model in model_list:
    the_class = getattr(the_module, model)
    some_var = the_class.query.filter_by(name='something').all()
Run Code Online (Sandbox Code Playgroud)