2017-10-06 5 views
0

J'essaye de construire une base de données avec sqlalchemy. J'ai deux tables: flow et krbr.sqlalchemy clé étrangère avec logique de correspondance complexe.

from __future__ import print_function 
import numpy as np 
import pandas as pd 
import sqlalchemy 
from sqlalchemy import create_engine 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy import Column, Integer, String 
import sqlalchemy_utils 
from sqlalchemy_utils.types.ip_address import IPAddressType 


Base = declarative_base() 

## Define the tables schema 

class Flow(Base): 
    __tablename__ = 'flow' 

    Id = Column(Integer, primary_key=True) 
    First = Column(Integer, index=True) 
    Protocol = Column(String(10)) 
    Src = Column(IPAddressType, index=True) 
    SrcPort = Column(Integer) 
    Dst = Column(IPAddressType, index=True) 
    DstPort = Column(Integer) 
    GroupId = Column(Integer) 
    Port = Column(String(10)) 
    VPort = Column(Integer) 
    IpTos = Column(String) 
    VlanId = Column(String) 
    VlanPri = Column(String) 
    Application = Column(String(100)) 
    Packets = Column(Integer) 
    Messages = Column(Integer) 
    Bytes = Column(Integer) 
    Last = Column(Integer) 
    #LearnedIPs alertable 
    #LearnedIPs learned-ip 
    # u'LearnedIPs new-ips', u'LearnedIPs subnet-name', 
    # u'LearnedIPs timestamp-sec', u'LearnedIPs total-ips', u'SrcSubnet', 
    # u'DstSubnet'], 
    # 'MPLS Exp' 


class Krbr(Base): 
    __tablename__ = 'krbr' 
    Id = Column(Integer, primary_key=True) 
    Src = Column(IPAddressType, index=True) 
    SrcPort = Column(Integer) 
    Dst = Column(IPAddressType, index=True) 
    DstPort = Column(Integer) 
    TimeNs = Column(Integer) 

quelques-unes des lignes dans flow est associée une ou plusieurs lignes de krbr.

Une rangée dans krbr est associée à une ligne dans flow si:

1) ils ont les mêmes valeurs de Src, Dst, SrcPort, DstPort

2) Ils sont proches dans le temps. c'est-à-dire np.abs(Flow.first - Krbr.TimeNs/1000000000) < threshold

Je me demande quelle est la bonne approche pour créer un lien entre les deux tables. c'est-à-dire donné une rangée d'une table, je veux pouvoir obtenir les rangées de l'autre table.

Je ne connais pas grand chose de sqlalchemy. Je suppose que je devrais définir une clé étrangère, mais je ne sais pas comment appliquer une relation aussi complexe.

+1

Je ne pense pas que la clé floue étrangère une logique comme celle que vous suggérez au point 2 est possible - une clé étrangère doit identifier de façon unique une ligne dans une autre table –

+0

Donc la bonne façon de le faire est de créer une nouvelle colonne dans chaque table qui est définie comme Src: SrcPort_Dst: DstPort_time_interval' puis d'utiliser cette colonne comme clé étrangère – Donbeo

Répondre

0

Voici un échantillon de « gestion de plusieurs chemins de jointure »:

from sqlalchemy import Integer, ForeignKey, String, Column 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy.orm import relationship 

Base = declarative_base() 

class Customer(Base): 
    __tablename__ = 'customer' 
    id = Column(Integer, primary_key=True) 
    name = Column(String) 

    billing_address_id = Column(Integer, ForeignKey("address.id")) 
    shipping_address_id = Column(Integer, ForeignKey("address.id")) 

    billing_address = relationship("Address") 
    shipping_address = relationship("Address") 

class Address(Base): 
    __tablename__ = 'address' 
    id = Column(Integer, primary_key=True) 
    street = Column(String) 
    city = Column(String) 
    state = Column(String) 
    zip = Column(String) 

En savoir plus sur « Handling Multiple chemins de jointure » Vous pouvez trouver à SQLAlchemy 0.9 Documentation

+1

Cela augmentera pendant mappe r heure de configuration. Il n'y a rien qui dirait à SQLA quelle clé étrangère les relations devraient utiliser. Vous devrez passer l'argument 'foreign_keys' à' relationship() '. –