当前位置: 首页 > article >正文

sqlalchemy连接dm8 get_columns BIGINT VARCHAR字段不显示

问题

标题即为问题,

问题出现原因

sqlalchemy对应的sqlalchemy_dm源码需要调整

版本说明

python 3.10

dmPython 2.5.5(2.4.8也可以)

sqlalchemy1.4.52

sqlalchemy_dm1.4.39

环境说明

部署环境 ubuntu20

开发环境window11   wsl2  ubuntu20

可能会出现的报错

AttributeError: module 'sqlalchemy.engine.result'has no attribute 'FullyBufferedResultProxy

 找不到dmPython 模块

AttributeError: type object 'DMDialect_dmPython' has no attribute 'dbapi'

(按照我的经验,这些报错都只是dmPython  dpi  和sqlalchemy 的兼容问题,尽量使用网络下载的方式安装dmPython)

离线安装方式请划到最后查阅

解决步骤

获取文件(sqlalchemy)

  1. window版本的dm8,安装一下(可能官网没有了,就联系公司的商务咨询一下,看能不能拿到)
  2. docker镜像

更改源码

我的需求一共是三个,识别BIGINT,VARCHAR,TINYINT这三个

所以需要调整的文件我列到下面,自行对比差异

sqlalchemy/sqlalchemy_dm/base.py(主要是get_columns需要更改)

 @reflection.cache
    def get_columns(self, connection, table_name, schema=None, **kw):
        self.trace_process('DMDialect', 'get_columns', connection, table_name, schema, **kw)
        """
        kw arguments can be:
            dm_resolve_synonyms
            dblink
        """
        resolve_synonyms = kw.get('dm_resolve_synonyms', False)
        dblink = kw.get('dblink', '')
        info_cache = kw.get('info_cache')

        (table_name, schema, dblink, synonym) = \
            self._prepare_reflection_args(connection, table_name, schema,
                                        resolve_synonyms, dblink,
                                        info_cache=info_cache)

        columns = []
        if self._supports_char_length:
            char_length_col = 'char_length'
        else:
            char_length_col = 'data_length'

        params = {"table_name": table_name}
        text = "SELECT column_name, data_type, %(char_length_col)s, "\
            "data_precision, data_scale, "\
            "nullable, data_default FROM ALL_TAB_COLUMNS%(dblink)s "\
            "WHERE table_name = :table_name"
        if schema is not None:
            params['owner'] = schema
            text += " AND owner = :owner "
        text += " ORDER BY column_id"
        text = text % {'dblink': dblink, 'char_length_col': char_length_col}

        c = connection.execute(sql.text(text), **params)

        for row in c:
            (colname, orig_colname, coltype, length, precision, scale, nullable, default) = \
                (self.normalize_name(row[0]), row[0], row[1], row[
                2], row[3], row[4], row[5] == 'Y', row[6])

            # 添加对 BIGINT 和 VARCHAR 类型的支持
            if coltype == 'NUMBER':
                coltype = _DMNumeric(precision, scale)
            elif coltype in ('VARCHAR2', 'NVARCHAR2', 'CHAR', 'VARCHAR'):  # 添加 VARCHAR
                coltype = self.ischema_names.get(coltype)(length)
            elif coltype == 'BIGINT':  # 添加 BIGINT
                coltype = sqltypes.BIGINT
            elif 'WITH TIME ZONE' in coltype:
                coltype = TIMESTAMP(timezone=True)
            else:
                coltype = re.sub(r'\(\d+\)', '', coltype)
                try:
                    coltype = self.ischema_names[coltype]
                except KeyError:
                    util.warn("Did not recognize type '%s' of column '%s'" %
                            (coltype, colname))
                    coltype = sqltypes.NULLTYPE

            cdict = {
                'name': orig_colname,
                'type': coltype,
                'nullable': nullable,
                'default': default,
                'autoincrement': 'auto',
            }
            if orig_colname.lower() == orig_colname:
                cdict['quote'] = True

            columns.append(cdict)
        return columns

sqlalchemy/sqlalchemy_dm/types.py(部分需要修改)


ischema_names = {
    'TINYINT': TINYINT,
    'BIGINT': BIGINT,
    'VARCHAR': VARCHAR,
    'VARCHAR2': VARCHAR,
    'NVARCHAR2': NVARCHAR,
    'CHAR': CHAR,
    'DATE': DATE,
    'DATETIME': DATETIME,
    'NUMBER': NUMBER,
    'BLOB': _DMBLOB,
    #'BLOB': _DMBinary,
    'BFILE': BFILE,
    'CLOB': CLOB,
    'NCLOB': NCLOB,
    'TIME WITH TIME ZONE':TIME,
    'TIMESTAMP': TIMESTAMP,
    'TIMESTAMP WITH TIME ZONE': TIMESTAMP,
    'INTERVAL DAY TO SECOND': INTERVAL,
    'FLOAT': FLOAT,
    'DOUBLE PRECISION': DOUBLE_PRECISION,
    'LONG': LONGVARCHAR,
    'BIT': BIT,
    'TEXT': _DMText,
    #'TEXT': VARCHAR,
    'INTEGER': _DMInteger,
    'INT': _DMInteger,
    'BINARY':DMBINARY
}

安装驱动到python环境

获取到window的文件后,将dm8/drivers/python/sqlalchemy放到python环境中

随便放一个地址

然后执行以下命令

python setup.py install

记住执行前,记得把环境原有的sqlalchemy和sqlalchemy_dm删除

如果还有其他问题,见招拆招即可

dmPython离线安装

这一步骤,仅适用于,dmPython只能离线安装的伙伴

氛围两个步骤

制作dmPython  rpm包

需要吧window中  drivers/python/dmPython放到docker中任意位置

因为离线方式暂时不是迫切的(我已经实现了)

而且部署环境也可以访问互联网,故先留下制作镜像和docker服务安装dmPython的随笔  如下

理解如下的命令

有个比较重要的事情,dpi的路径,是dm8  docker服务中的bin目录(整个copy过去就行)

# dm8 docker服务安装python3.10
apt-get  install software-properties-common -y
add-apt-repository ppa:deadsnakes/ppa
apt-get install python3.10

ls /usr/bin/python3*
update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 1
update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 2
update-alternatives --config python3
python3 --version

#dm8 制作dmPython rpm包
cd /opt/dmdbms
ls
cd  /opt/dmdbms/drivers/python/dmPython
apt-get update
apt-get install python3 -y
apt-get install python3.10-distutils -y
export DM_HOME=/opt/dmdbms
apt-get install build-essential  -y
apt-get install python3.10-dev  -y
apt-get install rpm -y
 
cp /opt/dmdbms/drivers/python/dpi/include/DPI.h    /usr/include/python3.10     
cp /opt/dmdbms/drivers/python/dpi/include/DPIext.h /usr/include/python3.10
cp /opt/dmdbms/drivers/python/dpi/include/DPItypes.h /usr/include/python3.10


python3 setup.py bdist_rpm





python3 setup.py install




apt-get install rpm -y

#开发服务安装dmPython
cd /usr/local/lib/python3.10/site-packages/dmPythonRpm
apt-get install alien -y
alien dmPython-2.4.8-8.1-py310-1.x86_64.rpm
dpkg -i dmpython_2.4.8-2_amd64.deb
pip uninstall dmPython -y
pip show dmPython
export PYTHONPATH=$PYTHONPATH:/usr/local/lib/python3.10/dist-packages
export LD_LIBRARY_PATH=/opt/dpi:$LD_LIBRARY_PATH
python3 -c "import dmPython; print(dmPython.__file__)"






export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/dpi/
echo $LD_LIBRARY_PATH
find / -name libdmdpi.so




rpm -ivh dmPython-2.4.8-8.1-py310-1.x86_64.rpm  --nodeps




cd /usr/local/lib/python3.10/site-packages/dmPythonRpm
rpm -ivh dmPython-2.4.8-8.1-py310-1.x86_64.rpm


apt-get autoremove --purge dmpython



alien dmPython-2.4.8-8.1-py310-1.x86_64.rpm
pip show dmPython
dpkg -i dmpython_2.4.8-2_amd64.deb
pip show dmPython
export PYTHONPATH=$PYTHONPATH:/usr/local/lib/python3.10/dist-packages

cp dmPython-2.4.8.egg-info /usr/local/lib/python3.10/site-packages/dmPython-2.4.8.egg-info
cp dmPython.cpython-310-x86_64-linux-gnu.so /usr/local/lib/python3.10/site-packages/dmPython.cpython-310-x86_64-linux-gnu.so







#参考资料

https://blog.csdn.net/qq_45458674/article/details/134399152


http://www.kler.cn/a/450162.html

相关文章:

  • 实践KDTS-WEB从mysql迁移到kingbasev9
  • 个人笔记:ORM数据库框架EFCore使用示例,运行通过,附源码
  • hCaptcha 图像识别 API 对接说明
  • 【蓝桥杯——物联网设计与开发】基础模块8 - RTC
  • Mono里运行C#脚本3—mono_jit_init
  • 玩转OCR | 探索腾讯云智能结构化识别新境界
  • W25Q128存储器详解
  • 微服务篇-深入了解 MinIO 文件服务器(你还在使用阿里云 0SS 对象存储图片服务?教你使用 MinIO 文件服务器:实现从部署到具体使用)
  • 如何详细地遵循RustDesk的步骤来搭建远程访问和自定义服务器?
  • 如何使用nvm来管理node版本
  • 线程的安全、volatile、synchronized
  • 【运维笔记】向日葵远程:输入法大写无法切换至小写
  • 【React中最优雅的异步请求】
  • vue3+vite一个IP对站点名称的前端curd更新-会议系统优化
  • Spark-Streaming receiver模式源码解析
  • Redis实现延迟任务 + RedisUtil升级
  • 音频接口:PDM TDM128 TDM256
  • QT-简单视觉框架代码
  • Spring Security 自动踢掉前一个登录用户,一个配置搞定!,网易前端社招面经
  • 前端框架Vue的路由机制
  • 【已解决】黑马点评项目Redis版本替换过程中误删数据库后前端显示出现的问题
  • 基于 SOME/IP 的动态服务发现与调用:原理、实现与示例全解析
  • selenium学习笔记(一)
  • 软件测试之非功能测试设计
  • 自然语言编写的prompt为啥比不上编程语言prompt高效?
  • LeetCode 209. 长度最小的子数组 (C++实现)