使用sqlalchemy设置oracle连接的当前架构

2024-04-19 21:24:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在将大量代码从cx_Oracle迁移到sqlalchemy。我正在努力解决的一点是,如何正确地设置应该用于查询的当前模式

我找到的方法是,如果db驱动程序支持,尝试将模式信息传递给create_engine中的连接字符串cx_Oracle没有

或者通过__table_args__将模式硬编码到声明性基本模型中,这在我的示例中并不有用,因为测试服务器和生产服务器上的模式不同

here所述使用schema_translate_map是很有希望的,但事实证明,我必须在每次查询之前调用execution_options(),这是不可行的

创建会话后,我运行了一个ALTER SESSION SET CURRENT_SCHEMA = myschema。但这感觉不对。特别是因为必须清理模式名,因为这是从配置文件读取的,必须像用户输入一样处理

现在的情况是这样的:

model.py:

# -*- coding: utf-8 -*-
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.hybrid import hybrid_property

Base = declarative_base()


class User(Base):
    __tablename__ = "user"

    id = Column(Integer, primary_key=True)
    firstname = Column(String)
    lastname = Column(String)

    @hybrid_property
    def full_name(self):
        return self.firstname + " " + self.lastname

    def __repr__(self):
        return f"{self.firstname} {self.lastname}"

app.py:

#!usr/bin/env python
# -*- coding: utf-8 -*-
import sqlalchemy
import sqlalchemy.orm

import model


class Application:
    def __init__(self, user, passwd, host, sid, schema):
        self._engine, self.session = Application.init_database(user, passwd, host, sid, schema)

    @staticmethod
    def init_database(user, passwd, host, sid, schema):
        db_url = f"oracle://{user}:{passwd}@{host}/{sid}"

        engine = sqlalchemy.create_engine(db_url, echo=True)
        session = sqlalchemy.orm.Session(bind=engine)

        session.execute(f"ALTER SESSION SET CURRENT_SCHEMA = {schema!s}")

        return engine, session

    def get_user(self, id):
        return self.session.query(model.User).filter_by(id=id).one_or_none()


if __name__ == "__main__":
    app = Application("username", "userpwd", "myhost", "mysid", "myschema")
    user = app.get_user(1)

    print(user.full_name)


Tags: importselfidhostreturnsqlalchemysessionschema