【问题标题】:What is the optimal way to show custom data from MSAccess DB at Wordpress site?在 Wordpress 站点上显示来自 MSAccess DB 的自定义数据的最佳方式是什么?
【发布时间】:2019-05-20 12:31:18
【问题描述】:

我需要熟练的 Wordpress 开发人员的建议。我的组织有内部 MS Access 数据库,其中包含大量表格、报告和输入表单。 DB的结构并不太复杂(人物信息、事件、第三方信息以及它们之间的不同关系)。我们希望在我们的 Wordpress 网站上显示此信息的一部分,该网站目前只有新闻部分。

因为我们数据库中的信息每天都在更新,我们也想在 MS Access DB 和 Wordpress (MySQL DB) 之间进行简单的同步。现在我试图找到连接 MS Access 和 Wordpress 的最佳方式。

目前我只看到这些方法:

  1. 发出导出请求并保存到 XML 文件。
  2. 导入 Wordpress 的 MySQL 数据库。
  3. 使用自定义字段功能(或开发自己的插件)在 Wordpress 网站上显示内容。

-或-

  1. 在与 Wordpress 站点相同的域上的一些非常轻量级的 PHP 引擎(例如 CodeIgniter)上构建自己的信息系统,它实际上将显示导入的内容。

这些变体每天都需要在数据库之间手动传输信息。而且我不知道 Wordpress 显示来自数据库的自定义数据的可能性。你能建议我在我的情况下你更喜欢使用什么方式吗?

附:使用的 MS Access 版本为 2007+(文件 .accdb)。字段、数据库和内容的名称是俄语。未来我们计划添加 2 种新语言(英语、乌克兰语)。 MS access DB 还包含人物照片。

---更新信息---

我能够使用以下技术进行半自动导入/导出操作:

  • Javascript 库 ACCESSdb(针对新的 DB 格式稍作修改)
  • Internet Explorer 11(用于运行 ADODB ActiveX)
  • 用于从 MSAccess 表中提取附件的小 VBS 脚本。
  • 最新的 jQuery
  • 用于自定义数据的 Wordpress 插件(高级自定义字段、自定义帖子类型 UI)
  • 已启用 Wordpress Rest-API(使用插件 JSON 基本身份验证、ACF 到 REST API)

起初,我在 Wordpress 网站上使用自定义帖子和自定义字段技术构建了数据方案。然后我在本地运行 JS 查询到 MSAccess DB,接收到我通过 jQuery 发送到 WP Rest-API 端点的信息。一键完成整个传输操作。 但由于安全限制,我无法通过 JS 自动上传文件。这可以在每个文件 +1 次点击中完成。

【问题讨论】:

    标签: javascript wordpress ms-access internet-explorer activex


    【解决方案1】:

    你的问题太笼统了。 它由两部分组成:1. 从 Access 导出和 2. 导入到 Wordpress。由于我不熟悉 Wordpress,我只能给你关于 1 部分的建议。至少谷歌显示有一些插件可以从 CSV 导入,如下所示: https://ru.wordpress.org/plugins/wp-ultimate-csv-importer/

    您可以创建一个运行 Access 的计划任务,该任务运行运行 VBA 功能的宏,如下所述: Running Microsoft Access as a Scheduled Task

    在该 VBA 函数中,您可以使用 ADODB.Stream 对象创建包含您的数据的 UTF-8 CSV 文件并上传到您网站的 FTP。

    我个人使用 python 脚本来做类似的事情。我更喜欢这种方式,因为它更加严格和可靠。有我的代码。请注意,我有两台 FTP 服务器:其中一台仅用于测试。

    # -*- coding: utf-8 -*-
    # 2018-10-31
    # 2018-11-28
    
    import os
    import csv
    from time import sleep
    from ftplib import FTP_TLS
    from datetime import datetime as dt
    import msaccess
    
    FTP_REAL = {'FTP_SERVER':r'your.site.com',
                'FTP_USER':r'username',
                'FTP_PW':r'Pa$$word'
                }
    
    FTP_WIP = {'FTP_SERVER':r'192.168.0.1',
                'FTP_USER':r'just_test',
                'FTP_PW':r'just_test'
                }
    
    def ftp_upload(fullpath:str, ftp_folder:str, real:bool):
        ''' Upload file to FTP '''
        try:
            if real:
                ftp_set = FTP_REAL
            else:
                ftp_set = FTP_WIP
            with FTP_TLS(ftp_set['FTP_SERVER']) as ftp:
                ftp.login(user=ftp_set['FTP_USER'], passwd=ftp_set['FTP_PW'])
                ftp.prot_p()
                # Passive mode off otherwise there will be problem
                # with another upload attempt
                # my site doesn't allow active mode :(
                ftp.set_pasv(ftp_set['FTP_SERVER'].find('selcdn') > 0)
                ftp.cwd(ftp_folder)
                i = 0
                while i < 3:
                    sleep(i * 5)
                    i += 1
                    try:
                        with open(fullpath, 'br') as f:
                            ftp.storbinary(cmd='STOR ' + os.path.basename(fullpath),
                                            fp=f)
                    except OSError as e:
                        if e.errno != 0:
                            print(f'ftp.storbinary error:\n\t{repr(e)}')
                    except Exception as e:
                        print(f'ftp.storbinary exception:\n\t{repr(e)}')
                    filename = os.path.basename(fullpath)
                    # Check if uploaded file size matches local file:
                    # IDK why but single ftp.size command sometimes returns None,
                    # run this first:
                    ftp.size(filename)
                    #input(f'overwrite it: {filename}')
                    ftp_size = ftp.size(os.path.basename(fullpath))
                    # import pdb; pdb.set_trace()
                    if ftp_size != None:
                        if ftp_size == os.stat(fullpath).st_size:
                            print(f'File \'{filename}\' successfully uploaded')
                            break
                        else:
                            print('Transfer failed')
                            # input('Press enter for another try...')
        except OSError as e:
            if e.errno != 0:
                return False, repr(e)
        except Exception as e:
            return False, repr(e)
        return True, None
    
    def make_file(content:str):
        ''' Make CSV file in temp directory and return True and fullpath '''
        fullpath = os.environ['tmp'] + f'\\{dt.now():%Y%m%d%H%M}.csv'
        try:
            with open(fullpath, 'wt', newline='', encoding='utf-8') as f:
                try:
                    w = csv.writer(f, delimiter=';')
                    w.writerows(content)
                except Exception as e:
                    return False, f'csv.writer fail:\n{repr(e)}' 
        except Exception as e:
            return False, repr(e)
        return True, fullpath
    
    def query_upload(sql:str, real:bool, ftp_folder:str, no_del:bool=False):
        ''' Run query and upload to FTP '''
        print(f'Real DB: {real}')
        status, data = msaccess.run_query(sql, real=real, headers=False)
        rec_num = len(data)
        if not status:
            print(f'run_query error:\n\t{data}')
            return False, data
        status, data = make_file(data)
        if not status:
            print(f'make_file error:\n\t{data}')
            return False, data
        fi = data
        status, data = ftp_upload(fi, ftp_folder, real)
        if not status:
            print(f'ftp_upload error:\n\t{data}')
            return False, data
        print(f'Done: {rec_num} records')
        if no_del: input('\n\nPress Enter to exit and delete file')
        os.remove(fi)
        return True, rec_num
    
    

    【讨论】:

    • 感谢漂亮的脚本,当然会有一个巨大的解决方法(按计划导出 CSV,通过 FTP 上传,通过 Chronos 导入),但似乎这是在之间传输数据的真正方式DB的。因此,第 1 部分几乎已构建完毕。
    猜你喜欢
    • 2021-01-17
    • 2017-02-10
    • 1970-01-01
    • 2015-12-11
    • 2017-07-06
    • 1970-01-01
    • 2016-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多