【问题标题】:retrieve data from online database using input file使用输入文件从在线数据库中检索数据
【发布时间】:2013-12-04 08:08:47
【问题描述】:

我在 MacOSX 上使用 Postgres 9.3。

如果有人能在这里指出正确的方向,我会非常高兴。我想编写一个连接到现有(在线)数据库(例如this one)并使用具有适当字符串(在本例中为 MRGID)的输入文件检索数据(在本例中为 shapefile)的函数。对不起,我没有任何代码,我真的不知道从哪里开始,我似乎没有找到任何线程。也许SQL 不是去这里的路吗?

输入文件示例;

species,mrgids
Sp1,4279
Sp1,8366
Sp1,21899
Sp1,21834
Sp1,7130
Sp1,1905
Sp1,21900
Sp1,5679
Sp1,5696

谢谢!

【问题讨论】:

  • 哦,那个站点也使用了一个 restful api...使用那个...http://www.marineregions.org/rest/getGazetteerRecordByMRGID.json/5696/ 其中5696 是 MRGID。 see their documentation,如果您仔细阅读,它们会展示很多非常有用的示例。
  • 干杯,我去看看!

标签: sql database postgresql


【解决方案1】:

几乎可以肯定,最好在数据库之外使用您选择的语言编写脚本。我会使用 Python 和 psycopg2,但是像 Ruby + Pg gem、Perl 和 DBI / DBD::Pg,甚至 PHP 和 PDO,都是同样合理的选择。

您的代码可以进行 HTTP 提取,然后(如果它类似于 CSV)使用 COPY 命令将数据加载到 PostgreSQL 中。如果是 shapefile,您可以将数据提供给 PostGISshp2pgsql 加载器,或者使用 GeomFromText PostGIS 函数制作单独的 INSERTs。

您可以从 PL/Pythonu 或 PL/Perlu 存储过程中进行 HTTP 获取,但与仅从脚本中进行此操作相比并没有真正的好处,而且它作为外部脚本会更加健壮。

所以,真的,你需要把这个问题分开。

您需要代码才能与感兴趣的网站对话,其中可能包括提交表单的 HTTP POST 等内容。或者,最好对专为自动脚本交互设计的站点使用web API。大多数简单的 RESTful API 都可以通过使用 Perl 的 LWP、Python 的 httplib 等库的脚本语言轻松使用。对于您链接到的站点,正如 user623952 提到的那样,有一个 RESTful API

然后您需要代码来获取感兴趣的数据,以及读取获取的数据并将其加载到 PostgreSQL 中的代码。您可能希望下载所有数据然后加载它,或者您可能希望在下载数据时将其流式传输到数据库中(管道到shp2pgsql 等)。

【讨论】:

  • @Jo 它有一点学习曲线,但如果您使用地理数据,PostGIS 将是一个救星。强烈推荐。
  • 干杯!可能也可以与 R 中的不同地图库一起使用。
【解决方案2】:

这是一个非常基本的 PHP 和 CURL 示例

我完全使用了您的输入文件并将其保存为input.txt

species,mrgids
Sp1,4279
Sp1,8366
Sp1,21899
Sp1,21834
Sp1,7130
Sp1,1905
Sp1,21900
Sp1,5679
Sp1,5696

这就是 PHP 和 CURL 的作用:

<?php 
$base_url = "http://www.marineregions.org/rest/getGazetteerRecordByMRGID.json/%s/";

// just get the input file into an array to use 
$csv = read_file("input.txt"); 

// if you want to see the format of $csv    
print "<pre>".print_r($csv,true)."</pre>";


// go through each csv item and run a curl request on it 
foreach($csv as $i => $data)
{
    $mrgids = $data['mrgids']; 

    $url = sprintf($base_url,$mrgids);

    $response = run_curl_request($url);  

    if ($response!==false)
    {
        //http://us2.php.net/manual/en/function.json-decode.php
        $json = json_decode($response,true); 

        if (!is_null($json))
        {
            // this is where you would write the code to stick this info in 
            // your DB or do whatever you want with it...
            print "<pre>$url \n".print_r($json,true)."\n\n</pre>";
        }
        else 
        {
            print "error:  response was not proper JSON for $url <br/><br/>";
            print $response."<br/><br/><br/>"; 
        }
    }
    else
    {
        print "error:  response was false for $url <br/><br/>";
    }

}


function read_file($filename, $has_headers=true, $assoc=true) 
{
    $headers = array(); 
    $row = 1;

    if (($handle = fopen($filename, "r")) !== FALSE) 
    {
        $return = array(); 

        if ($has_headers) 
        {
            if (($data = fgetcsv($handle, 1000, ",")) !==false)
            {
                $headers = $data; 
            }
        }
        while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) 
        {
            if ($assoc) 
            {
                $temp = array(); 
                foreach($headers as $hi => $header)
                {
                    $temp[$header] = (isset($data[$hi])) ? $data[$hi] : ''; 
                }
                $return[] = $temp; 
            }
            else 
            {
                $return[] = $data; 
            }
        }   
        fclose($handle);
    }
    else
    {
        $return = false; 
    }

    return $return; 
}


// requires PHP CURL extension 
// http://php.net/manual/en/function.curl-setopt.php
function run_curl_request($url)
{ 
    // create curl resource 
    $ch = curl_init();  

    $defaults = array( 
        CURLOPT_POST => false, 
        CURLOPT_HEADER => false, 
        CURLOPT_URL => $url, 
        CURLOPT_FRESH_CONNECT => true, 
          CURLOPT_FAILONERROR => true,  
        CURLOPT_RETURNTRANSFER => true, 
        CURLOPT_FORBID_REUSE => true, 
        CURLOPT_TIMEOUT => 4 
    ); 

   curl_setopt_array($ch, $defaults); 


    // $output contains the output string 
    $output = curl_exec($ch); 

    // close curl resource to free up system resources 
    curl_close($ch);  

    return $output; 
}


?>

如果它成功了,你会得到一堆这样的输出

http://www.marineregions.org/rest/getGazetteerRecordByMRGID.json/4279/ 
Array
(
    [MRGID] => 4279
    [gazetteerSource] => IHO 23-3rd: Limits of Oceans and Seas, Special Publication 23, 3rd Edition 1953, published by the International Hydrographic Organization.
    [placeType] => IHO Sea Area
    [latitude] => 39.749996185303
    [longitude] => 5.0942182540894
    [minLatitude] => 35.071937561035
    [minLongitude] => -6.0326728820801
    [maxLatitude] => 44.42805480957
    [maxLongitude] => 16.221109390259
    [precision] => 1079464.0796258
    [preferredGazetteerName] => Mediterranean Sea - Western Basin
    [preferredGazetteerNameLang] => English
    [status] => standard
    [accepted] => 4279
)

注意事项:

【讨论】:

  • 哦...好吧...那么您将如何处理这些数据?将其粘贴在您的数据库中?确保使用pdomysqli... 并寻找这样的帖子:PHP PDO batch insert from multi dimensional array failing to insert into MySQL.. 任何插入关联数组的内容。而不是将数组输出到屏幕上,而是应该进行插入的地方。为了方便您自己,请使列名与其字段名相同。
  • 是的,我想我会使用 PostGIS 并将数据导入我的 Postgres 数据库。然后计划是使用 R 进行地理统计。我对 R 很熟悉,但我在从 Postgres 到 R 的工作流程中发现了 a good thread
  • proooobably 大声笑...无论如何我写这个例子很有趣.....!我不知道 R 或 PostGIS。不过,无论如何,请使用该站点拥有的 RESTful API。它会让你的生活轻松很多。响应是 JSON,因此您可能也应该研究一下。
  • 获取到的Json格式的数据,是否包含与同区域的shapefile相同的信息?我是这里的菜鸟,所以我不确定如何继续拥有这些数据,可能会放回我的数据库并用于地理统计?任何的想法?干杯
猜你喜欢
  • 1970-01-01
  • 2021-10-20
  • 1970-01-01
  • 2023-04-04
  • 2017-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-25
相关资源
最近更新 更多