首页 > 解决方案 > 如何在 python sqlalchemy 中为 select() 提供通用模块?

问题描述

我的表 Table1 Table2 Table3 有 3 个来自 SQLAlchemy 的模型类

'''

from sqlalchemy import create_engine , text , select, MetaData, Table  ,func , Column , String , Integer
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
import sqlalchemy
from settings import DATABASE_URI
engine=create_engine(DATABASE_URI)
Base = declarative_base()
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
metadata = MetaData(bind=None)
session = Session()

class Table1(Base):
    __tablename__ = 'table1'
    id = Column(u'id', Integer(), primary_key=True)
    name1 = Column(u'name1', String(50))

class Table2(Base):
    __tablename__ = 'table2'
    id = Column(u'id', Integer(), primary_key=True)
    name2 = Column(u'name2', String(50))

class Table3(Base):
    __tablename__ = 'table3'
    id = Column(u'id', Integer(), primary_key=True)
    name3 = Column(u'name3', String(50))


class connectionTest():
    def wrapper_connection(self,table,column,value):
        #SELECT column FROM table1 WHERE column = value
        query = session.query(table)
        q = query.filter_by(column = value)
        session.execute(q)


def main():
    ct = connectionTest()
    t1 = Table1()
    t2 = Table2()
    t3 = Table3()
    ct.wrapper_connection(t1,t1.name1, "Table1_Value_Information")
    ct.wrapper_connection(t2,t2.name2, "Table2_Value_Information")
    ct.wrapper_connection(t3,t3.name3, "Table3_Value_Information")

if __name__ == '__main__':
    main()

'''

我希望包装器连接能够处理具有不同列的所有 3 个不同的表。基本上是为了使其尽可能通用,以通过 SQLAlchemy ORM 或核心库处理与 (#SELECT column FROM table1 WHERE column = value) 子句相关的任何条件。

我面临的问题就在这一行。'q = query.filter_by(列 = 值)'

我试图从函数属性 t1.name1 传递列信息

ct.wrapper_connection(t1,t1.name1, "Table1_Value_Information")

我面临的错误:

Traceback(最近一次调用最后一次):文件“C:\Users<username>\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\orm\base.py”,第 406 行,在 _entity_descriptor 中返回 getattr (实体,键)

AttributeError:类型对象“Table1”没有属性“列”

标签: pythonsqlflasksqlalchemyflask-sqlalchemy

解决方案


问题中的代码需要三处更改:

  • wrapper_connection方法中,使用Query.filter代替,Query.filter_by因为它会直接接受一个列对象
  • Base.metadata.create_all()在声明模型类之前不要调用
  • t1 = Table1()创建该类的一个新实例-Table1一行。你想查询表,所以直接使用模型类。
class connectionTest:
    def wrapper_connection(self, table, column, value):
        # SELECT column FROM table1 WHERE column = value
        query = session.query(table)
        # We have the column object, so use filter
        # instead of filter_by
        q = query.filter(column == value)
        session.execute(q)


# Create the tables after the model classes have been declared.
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()


def main():
    ct = connectionTest()
    # Use the model classes directly.
    ct.wrapper_connection(Table1, Table1.name1, "Table1_Value_Information")
    ct.wrapper_connection(Table2, Table2.name2, "Table2_Value_Information")
    ct.wrapper_connection(Table3, Table3.name3, "Table3_Value_Information")



推荐阅读