Python 将MySQL表传输到另一台服务器的最佳实践?
我有一个位于“主服务器”上的系统,它定期将大量信息从MySQL数据库传输到web上的另一台服务器 这两台服务器都有一个MySQL服务器和一个运行Apache的服务器。我想要一个易于使用的解决方案 目前我正在调查:Python 将MySQL表传输到另一台服务器的最佳实践?,python,web-services,database-design,Python,Web Services,Database Design,我有一个位于“主服务器”上的系统,它定期将大量信息从MySQL数据库传输到web上的另一台服务器 这两台服务器都有一个MySQL服务器和一个运行Apache的服务器。我想要一个易于使用的解决方案 目前我正在调查: XMLRPC 宁静服务 处理脚本的简单POST 套接字传输 我主人的应用程序是TurboGears应用程序,所以我更喜欢“pythonic”即不那么难看的解决方案。通过FTP/SCP或类似的方式将转储的表复制到另一台服务器可能很快,但在我看来,这也是非常(快速)和肮脏的,我希望有一
- XMLRPC
- 宁静服务
- 处理脚本的简单POST
- 套接字传输
Tom假设您的情况允许这种安全性,您忘记了一种传输机制:只需打开从一台服务器到另一台服务器的mysql连接 在我看来,我首先要考虑一个脚本,它定期在写服务器上运行,并打开到读服务器的只读db连接(增加了一点安全性)和到它自己的数据库服务器的完整连接 然后如何继续取决于数据(是否只是要处理的插入?是否必须镜像删除?插入与更新的数量?等等),但基本上,您可以编写一个脚本,从读取服务器提取数据并立即将其处理到写入服务器
另外,mysql服务器复制是否可以工作,或者作为一种解决方案,它是否会过度膨胀?如果您可以访问mysql的数据端口,并且不介意不断的网络流量,您可以使用。如果表很小,您可以发送整个表,只需删除旧数据,然后在远程服务器上插入新数据,那么有一个简单的通用解决方案:您可以使用表数据创建一个长字符串,并通过webservice发送。下面是它的实现方式。请注意,这远不是完美的解决方案,只是我如何在网站之间传输小型简单表格的一个示例:
function DumpTableIntoString($tableName, $includeFieldsHeader = true)
{
global $adoConn;
$recordSet = $adoConn->Execute("SELECT * FROM $tableName");
if(!$recordSet) return false;
$data = "";
if($includeFieldsHeader)
{
// fetching fields
$numFields = $recordSet->FieldCount();
for($i = 0; $i < $numFields; $i++)
$data .= $recordSet->FetchField($i)->name . ",";
$data = substr($data, 0, -1) . "\n";
}
while(!$recordSet->EOF)
{
$row = $recordSet->GetRowAssoc();
foreach ($row as &$value)
{
$value = str_replace("\r\n", "", $value);
$value = str_replace('"', '\\"', $value);
if($value == null) $value = "\\N";
$value = "\"" . $value . "\"";
}
$data .= join(',', $row);
$recordSet->MoveNext();
if(!$recordSet->EOF)
$data .= "\n";
}
return $data;
}
// NOTE: CURRENTLY FUNCTION DOESN'T SUPPORT HANDLING FIELDS HEADER, SO NOW IT JUST SKIPS IT
// IF NECESSARRY
function FillTableFromDumpString($tableName, $dumpString, $truncateTable = true, $fieldsHeaderIncluded = true)
{
global $adoConn;
if($truncateTable)
if($adoConn->Execute("TRUNCATE TABLE $tableName") === false)
return false;
$rows = explode("\n", $dumpString);
$startRowIndex = $fieldsHeaderIncluded ? 1 : 0;
$query = "INSERT INTO $tableName VALUES ";
$numRows = count($rows);
for($i = $startRowIndex; $i < $numRows; $i++)
{
$row = explode(",", $rows[$i]);
foreach($row as &$value)
{
if($value == "\"\\N\"")
$value = "NULL";
}
$query .= "(". implode(",", $row) .")";
if($i != $numRows - 1)
$query .= ",";
}
if($adoConn->Execute($query) === false)
{
return false;
}
return true;
}
函数dumptabletintostring($tableName,$includefeldsheader=true)
{
全球$adoConn;
$recordSet=$adoConn->Execute(“从$tableName中选择*);
如果(!$recordSet)返回false;
$data=“”;
如果($includefeldsheader)
{
//获取字段
$numFields=$recordSet->FieldCount();
对于($i=0;$i<$numFields;$i++)
$data.=$recordSet->FetchField($i)->name.,”;
$data=substr($data,0,-1)。“\n”;
}
而(!$recordSet->EOF)
{
$row=$recordSet->GetRowAssoc();
foreach($row as&$value)
{
$value=str\u replace(“\r\n”,”,$value);
$value=str\u replace(“,“\\”,$value);
如果($value==null)$value=“\\N”;
$value=“\”.$value。“\”;
}
$data.=联接(“,”,$row);
$recordSet->MoveNext();
如果(!$recordSet->EOF)
$data.=“\n”;
}
返回$data;
}
//注意:当前函数不支持处理字段头,所以现在它只是跳过它
//必要时
函数FillTableFromDumpString($tableName,$dumpString,$truncateTable=true,$fieldsHeaderIncluded=true)
{
全球$adoConn;
如果($truncateTable)
if($adoConn->Execute(“截断表$tableName”)==false)
返回false;
$rows=分解(“\n”,$dumpString);
$startRowIndex=$fieldsHeaderIncluded?1:0;
$query=“插入到$tableName值中”;
$numRows=计数($rows);
对于($i=$startRowIndex;$i<$numRows;$i++)
{
$row=分解(“,”,$rows[$i]);
foreach($row as&$value)
{
如果($value==“\\\N\”)
$value=“NULL”;
}
$query.=“(“.inpode(“,”,$row)。”)”;
如果($i!=$numRows-1)
$query.=“,”;
}
如果($adoConn->Execute($query)==false)
{
返回false;
}
返回true;
}
如果您有大型表,那么我认为您只需要发送新数据。向远程服务器请求最新的时间戳,然后从主服务器读取所有较新的数据,并以通用方式(如上所示)或非通用方式(在这种情况下,您必须为每个表编写单独的函数)发送数据。服务器1:将行转换为JSON,使用JSON数据调用second的RESTful api 服务器2:监听URI,例如POST/data,将json数据转换回字典或ORM对象,插入数据库
sqlalchemy/sqlobject和simplejson是您所需要的。如果您使用的是MyISAM或归档表,那么我强烈推荐