Python 如何使用“查询”选择查询;作为「;并在SQLAlchemy ORM中连接表

Python 如何使用“查询”选择查询;作为「;并在SQLAlchemy ORM中连接表,python,mysql,sqlalchemy,fastapi,Python,Mysql,Sqlalchemy,Fastapi,我将使用sqlalchemy创建查询选择join,如下所示: 选择位置。*,device.name作为devicename 从`position`JOIN`设备` ON position.id_device=device.id 按位置订购.id\u设备 因此,在python文件中,我创建如下查询: result = sql.query(Position, Device).\ join(Device, Position.id_device == Device.id).\

我将使用
sqlalchemy
创建查询
选择join
,如下所示:

选择位置。*,device.name作为devicename
从`position`JOIN`设备`
ON position.id_device=device.id
按位置订购.id\u设备
因此,在python文件中,我创建如下查询:

result = sql.query(Position, Device).\
            join(Device, Position.id_device == Device.id).\
            order_by(Position.id_device).first()
我得到的结果是:

[
  {
    "id": 1,
    "size": "600x300",
    "price": 150,
    "id_category": 0,
    "id_device": 1,
    "impression": 9999,
    "status": 1,
    "name": "Home Top Banner",
    "id_website": 1
  },
  {
    "deleted_at": null,
    "status": 1,
    "name": "Desktop",
    "id": 1
  }
]
我想要作为上面的
mysql
查询的结果是:

[
  {
    "id": 1,
    "size": "600x300",
    "price": 150,
    "id_category": 0,
    "id_device": 1,
    "impression": 9999,
    "status": 1,
    "name": "Home Top Banner",
    "id_website": 1,
    "devicename": "Desktop",
  }
]
主要代码流:

[...]
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
[...]

from sqlalchemy.orm import Session

def db_session() -> Generator:
    """
    Get database connection with DI (Dependencies Injection)
    """
    try:
        dbsession = SessionLocal()
        yield dbsession
    finally:
        dbsession.close()
    
@router.get('/{ad_type}')
def ad_unit(
        ad_type: str,
        sql: Session = Depends(db_session)
):
    """Display ads unit of the available product"""
    result = get_position(sql, ad_type=ad_type)
    return result
    [...]    

def get_position(sql: Session, ad_type: str):
    result = sql.query(Position, Device).\
              join(Device, Position.id_device == Device.id).\
              order_by(Position.id_device).first()
    [...]
模型类:

from sqlalchemy import Column
from sqlalchemy.dialects import mysql

from app.settings.mysql_settings import Base


class Position(Base):
    """A class used to represent position table (ads price list & dimensions)"""
    __tablename__ = 'position'

    id = Column(mysql.INTEGER(display_width=11, unsigned=True), primary_key=True,
                index=True, autoincrement=True)
    id_device = Column(mysql.INTEGER(display_width=11), nullable=True)
    id_website = Column(mysql.INTEGER(display_width=11), nullable=True)
    id_category = Column(mysql.INTEGER(display_width=11), nullable=True)
    name = Column(mysql.VARCHAR(length=50, collation="utf8_unicode_ci"), nullable=True)
    price = Column(mysql.INTEGER(display_width=11), nullable=True)
    status = Column(mysql.TINYINT(display_width=1), nullable=True, default=1)
    size = Column(mysql.TEXT(collation="utf8_unicode_ci"), nullable=True)
    impression = Column(mysql.DOUBLE(), nullable=False, default=0)


class Device(Base):
    """A class used to represent a list of device type for ads unit e.g: Mobile, Desktop, etc."""
    __tablename__ = 'device'

    id = Column(mysql.INTEGER(display_width=11), primary_key=True,
                index=True, autoincrement=True)
    name = Column(mysql.VARCHAR(length=50, collation="latin1_swedish_ci"), nullable=True)
    status = Column(mysql.TINYINT(display_width=1), nullable=True, default=1)
    deleted_at = Column(mysql.TIMESTAMP(), nullable=True)
我已经尝试了很多方法来获得我想要的结果,通过合并/合并结果和其他方法,但都不起作用。我认为有一种特定的方法可以通过
sqlalchemy
获得我想要的结果,但是我在文档中找不到它,因为有太多的引用


如需任何帮助,将不胜感激。

要翻译如下查询:

SELECT users.name AS users_name,
        addresses_1.email_address AS addresses_1_email_address,
        addresses_2.email_address AS addresses_2_email_address
FROM users JOIN addresses AS addresses_1
        ON users.id = addresses_1.user_id
JOIN addresses AS addresses_2
        ON users.id = addresses_2.user_id
WHERE addresses_1.email_address = ?
        AND addresses_2.email_address = ?
('jack@google.com', 'j25@yahoo.com')
等效的SQL alchemy语法如下:

>>> from sqlalchemy.orm import aliased
>>> adalias1 = aliased(Address)
>>> adalias2 = aliased(Address)
SQL>>> for username, email1, email2 in \
...     session.query(User.name, adalias1.email_address, adalias2.email_address).\
...     join(User.addresses.of_type(adalias1)).\
...     join(User.addresses.of_type(adalias2)).\
...     filter(adalias1.email_address=='jack@google.com').\
...     filter(adalias2.email_address=='j25@yahoo.com'):
...     print(username, email1, email2)

嗯,我终于找到了答案,我尝试了很多方法,你知道什么是
print
save my day:D

所以,我在这里找到了两个解决方案,这两个都是我想要的。第一个仍然使用ORM样式,第二个仍然使用
raw
查询

j = join(Position, Device, Position.id_device == Device.id)
stmt = select([Position, Device.name.label('devicename')]).select_from(j)
result = sql.execute(stmt)
return result.fetchall()

# or by raw query
result = sql.execute("""SELECT position.*, device.name as devicename
    FROM `position`
    JOIN `device` on position.id_device = device.id
    ORDER BY position.id_device""")
return result.fetchall()

就这样。谢谢大家的帮助。

一个很简单的方法是查询(位置、表、设备、名称、标签('devicename'))。我得到了一个数组
[1,1,0,“Home Top Banner”,150,1,“600x300”,9999,“Desktop”]
而不是JSON编码器将结果对象作为元组(某种程度上是元组)处理的单个对象数组。如果您添加一个步骤,将转换为dict列表,它将按您的需要显示出来。例如,
result=[dict(result)]
,嗯,也许你是对的,我会想办法解决later@metaphor如果我看一下,您似乎不应该包括
设备两次。尝试以下操作:
sql.query(Position).join(Device,Position.id\u Device==Device.id).order\u by(Position.id\u Device).first()