2013-02-07 13 views
1

我正在編寫一個腳本來同步Adwords帳戶和本地數據庫機智Sqlalchemy。 我下面的AdWords API的對象層次,所以我的第一個表是「運動」,二是「廣告組」SQLalchemy重複條目錯誤爲未知的值

這裏是如何我定義兩個:

class Campaign(Base): 

__tablename__ = 'aw_campaigns' 

id = Column(Integer, primary_key=True) 
name = Column(String(99)) 
impressions = Column(Integer) 
serving_status = Column(String(99)) 
start_date = Column(String(99)) 
status = Column(String(99)) 

def __init__(self, id, name, impressions, serving_status, start_date, status): 
    self.id = id 
    self.name = name 
    self.impressions = impressions 
    self.serving_status = serving_status 
    self.start_date = start_date 
    self.status = status 

class Adgroup(Base): 

__tablename__ = 'aw_adgroups' 

id = Column(Integer, primary_key=True) # , primary_key=True 
name = Column(String(99)) 
camp_id = Column(Integer, ForeignKey('aw_campaigns.id')) # , ForeignKey('aw_campaigns.id') 
camp_name = Column(String(99)) 
ctr = Column(Float) 
cost = Column(Float) 
impressions = Column(Integer) 
clicks = Column(Integer) 
status = Column(String(99)) 

def __init__(self, id, name, camp_id, camp_name, ctr, cost, impressions, clicks, status): 
    self.id = id 
    self.name = name 
    self.camp_id = camp_id 
    self.camp_name = camp_name 
    self.ctr = ctr 
    self.cost = cost 
    self.impressions = impressions 
    self.clicks = clicks 
    self.status = status 

我查詢API ,然後生成對象的列表在廣告組表中的行:

adgr_query = 'SELECT CampaignId, CampaignName, Clicks, Cost, Impressions, Ctr, Id, KeywordMaxCpc, Name, Settings, Status' 
adgr_page = ad_group_serv.Query(adgr_query)[0]['entries'] 

adgr_ins = [Adgroup(i['id'], 
      i['name'], 
      i['campaignId'], 
      i['campaignName'], 
      i['stats']['ctr'], 
      i['stats']['cost']['microAmount'], 
      i['stats']['impressions'], 
      i['stats']['clicks'], 
      i['status']) for i in adgr_page if int(i['id']) not in adgr_exist] 

但是當我犯我的錯誤:

(IntegrityError) (1062, "Duplicate entry '2147483647' for key 'PRIMARY'") 

問題是我不知道該值來自哪裏。

'2147483647' in [i['id'] for i in adgr_page] 
>>> False 
'2147483647' in str(adgr_page) 
>>> False 

我對此很感興趣。

+0

嘗試一個整數? '... 2147483647 in ...' – zzzeek

+0

沒有什麼變化。此外,我使用一個隨機數作爲id(主鍵),並刪除了外鍵,同樣的錯誤。 –

+0

您需要查看正在發佈的SQL並深入挖掘。 – zzzeek

回答

1

看起來你有整數溢出的地方。

症狀:2147483647是2 ** 31-1 - 表示32位被用來存儲數。

AdGroup.Id字段的類型xsd:long其具有64位的長度。

Python本身對整數值的大小沒有限制,但數據庫可以具有這樣的限制。

簡短的解決方案:

嘗試使用BigInteger SQLTYPE型id = Column(BigInteger, primary_key=True)與同爲camp_id,其餘的xsd:長值從AdWords API的到來。 SQLAlchemy有機會選擇數據庫特定的大整數列類型。或者你可以使用String(64)作爲id的類型。但在這種情況下,您需要額外的步驟來生成主鍵。

您對AdWords API的查詢返回多少條目?是否有更多的2 ** 32記錄?我懷疑它 - 你的數據庫不可能處理大約4200萬條記錄。

解決方案2 - 長期

雖然我會建議不信任的主鍵完整性,外部源,並會依賴於數據庫中使用自動增量生成主鍵,並依靠SQLAlchemy的處理外鍵人口基礎數據庫生成主鍵:

class Adgroup(Base): 
    __tablename__ = 'aw_adgroups' 
    id = Column(Integer, Sequence('adgroup_seq'), primary_key=True) # , primary_key=True 
    adGroupId = Column(String(64)) 
    campaignId = Column(Integer,ForeignKey('aw_campaigns.id')) 
    campaign = relationship("Campaign", backref = "adgroup") 
    ... 

class Campaign(Base): 
    __tablename__ = 'aw_campaigns' 
    id = Column(Integer, Sequence('adgroup_seq'), primary_key=True) 
    campaignId = Column(String(64)) 
    ... 

看起來也像你可能需要做的CAMPAIGNID和adGroupId查找 - 這樣你就可以將它們添加索引。

然後創建廣告系列和廣告組的對象,只是它們之間的關係添加。代碼將取決於您想要使用的關係類型 - 一對多或多對多。查詢sqlalchemy relationship manual瞭解更多詳情。

ag = AdGroup(**kwargs) 
camp = Campaign(**kwargs) 
ag.campaign = camp 
session.add(ag)