Merge Master in geni-v3 conflict resolution
[sfa.git] / sfa / senslab / slabpostgres.py
1 from sqlalchemy import create_engine
2 from sqlalchemy.orm import sessionmaker
3
4 from sfa.util.config import Config
5 from sfa.util.sfalogging import logger
6
7 from sqlalchemy import Column, Integer, String
8 from sqlalchemy import Table, MetaData
9 from sqlalchemy.ext.declarative import declarative_base
10
11 from sqlalchemy.dialects import postgresql
12
13 from sqlalchemy.exc import NoSuchTableError
14
15
16 #Dict holding the columns names of the table as keys
17 #and their type, used for creation of the table
18 slice_table = {'record_id_user': 'integer PRIMARY KEY references X ON DELETE \
19 CASCADE ON UPDATE CASCADE','oar_job_id':'integer DEFAULT -1',  \
20 'record_id_slice':'integer', 'slice_hrn':'text NOT NULL'}
21
22 #Dict with all the specific senslab tables
23 tablenames_dict = {'slab_xp': slice_table}
24
25
26 SlabBase = declarative_base()
27
28
29         
30 class SenslabXP (SlabBase):
31     """ SQL alchemy class to manipulate slice_senslab table in 
32     slab_sfa database.
33     
34     """
35     __tablename__ = 'slab_xp' 
36
37
38     slice_hrn = Column(String)
39     job_id = Column(Integer, primary_key = True)
40     end_time = Column(Integer, nullable = False)
41
42
43     #oar_job_id = Column( Integer,default = -1)
44     #node_list = Column(postgresql.ARRAY(String), nullable =True)
45     
46     def __init__ (self, slice_hrn =None, job_id=None,  end_time=None):
47         """
48         Defines a row of the slice_senslab table
49         """
50         if slice_hrn:
51             self.slice_hrn = slice_hrn
52         if job_id :
53             self.job_id = job_id
54         if end_time:
55             self.end_time = end_time
56             
57             
58     def __repr__(self):
59         """Prints the SQLAlchemy record to the format defined
60         by the function.
61         """
62         result = "<slab_xp : slice_hrn = %s , job_id %s end_time = %s" \
63             %(self.slice_hrn, self.job_id, self.end_time)
64         result += ">"
65         return result
66           
67    
68           
69 class SlabDB:
70     """ SQL Alchemy connection class.
71     From alchemy.py
72     """
73     def __init__(self, config, debug = False):
74         self.sl_base = SlabBase
75         dbname = "slab_sfa"
76         if debug == True :
77             l_echo_pool = True
78             l_echo = True 
79         else :
80             l_echo_pool = False
81             l_echo = False 
82
83         self.slab_session = None
84         # the former PostgreSQL.py used the psycopg2 directly and was doing
85         #self.connection.set_client_encoding("UNICODE")
86         # it's unclear how to achieve this in sqlalchemy, nor if it's needed 
87         # at all
88         # http://www.sqlalchemy.org/docs/dialects/postgresql.html#unicode
89         # we indeed have /var/lib/pgsql/data/postgresql.conf where
90         # this setting is unset, it might be an angle to tweak that if need be
91         # try a unix socket first - omitting the hostname does the trick
92         unix_url = "postgresql+psycopg2://%s:%s@:%s/%s"% \
93             (config.SFA_DB_USER, config.SFA_DB_PASSWORD, \
94                                     config.SFA_DB_PORT, dbname)
95
96         # the TCP fallback method
97         tcp_url = "postgresql+psycopg2://%s:%s@%s:%s/%s"% \
98             (config.SFA_DB_USER, config.SFA_DB_PASSWORD, config.SFA_DB_HOST, \
99                                     config.SFA_DB_PORT, dbname)
100         for url in [ unix_url, tcp_url ] :
101             try:
102                 self.slab_engine = create_engine (url, echo_pool = \
103                                             l_echo_pool, echo = l_echo)
104                 self.check()
105                 self.url = url
106                 return
107             except:
108                 pass
109         self.slab_engine = None
110         raise Exception, "Could not connect to database"
111     
112     
113     
114     def check (self):
115         """ Cehck if a table exists by trying a selection
116         on the table. 
117         
118         """
119         self.slab_engine.execute ("select 1").scalar()
120         
121         
122     def session (self):
123         """
124         Creates a SQLalchemy session. Once the session object is created
125         it should be used throughout the code for all the operations on 
126         tables for this given database.
127         
128         """ 
129         if self.slab_session is None:
130             Session = sessionmaker()
131             self.slab_session = Session(bind = self.slab_engine)
132         return self.slab_session
133         
134     def close_session(self): 
135         """
136         Closes connection to database. 
137         
138         """
139         if self.slab_session is None: return
140         self.slab_session.close()
141         self.slab_session = None   
142         
143
144     def exists(self, tablename):
145         """
146         Checks if the table specified as tablename exists.
147     
148         """
149        
150         try:
151             metadata = MetaData (bind=self.slab_engine)
152             table = Table (tablename, metadata, autoload=True)
153             return True
154         
155         except NoSuchTableError:
156             logger.log_exc("SLABPOSTGRES tablename %s does not exists" \
157                             %(tablename))
158             return False
159        
160     
161     def createtable(self):
162         """
163         Creates all the table sof the engine.  
164         Uses the global dictionnary holding the tablenames and the table schema.
165     
166         """
167
168         logger.debug("SLABPOSTGRES createtable SlabBase.metadata.sorted_tables \
169             %s \r\n engine %s" %(SlabBase.metadata.sorted_tables , slab_engine))
170         SlabBase.metadata.create_all(slab_engine)
171         return
172     
173
174
175 slab_alchemy = SlabDB(Config())
176 slab_engine = slab_alchemy.slab_engine
177 slab_dbsession = slab_alchemy.session()