massive update
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
import os
|
||||
from typing import List
|
||||
from datetime import date
|
||||
|
||||
import psycopg2
|
||||
|
||||
@ -12,6 +13,17 @@ class DataProvider:
|
||||
self._connection: psycopg2 = psycopg2.connect(params)
|
||||
self.params = params
|
||||
|
||||
def delete_tables(self):
|
||||
cur = self._connection.cursor()
|
||||
cur.execute(
|
||||
"SELECT table_schema,table_name FROM information_schema.tables WHERE table_schema = 'public' ORDER BY table_schema,table_name")
|
||||
rows = cur.fetchall()
|
||||
for row in rows:
|
||||
print
|
||||
"dropping table: ", row[1]
|
||||
cur.execute("drop table " + row[1] + " cascade")
|
||||
cur.close()
|
||||
|
||||
def migrate(self):
|
||||
with self._connection.cursor() as cur:
|
||||
f = open(os.path.join("migrations", "201831231.2049_initial.sql"),
|
||||
@ -22,31 +34,27 @@ class DataProvider:
|
||||
|
||||
def get_enterprises(self) -> List[Enterprise]:
|
||||
with self._connection.cursor() as cursor:
|
||||
cursor.execute("SELECT id, name, short_name FROM enterprise;")
|
||||
cursor.execute("SELECT id FROM enterprise;")
|
||||
res = [Enterprise(
|
||||
ent_id,
|
||||
ent_id[0],
|
||||
self.get_activities_by_enterprpise(ent_id),
|
||||
self.get_divisions_by_enterprise(ent_id),
|
||||
self.get_contact_info_by_enterprise(ent_id),
|
||||
name,
|
||||
short_name
|
||||
) for ent_id, name, short_name in cursor.fetchall()]
|
||||
self.get_contact_info_by_enterprise(ent_id)
|
||||
) for ent_id in cursor.fetchall()]
|
||||
self._connection.commit()
|
||||
return res
|
||||
|
||||
def get_enterprise_by_id(self, ent_id: int):
|
||||
with self._connection.cursor() as cursor:
|
||||
cursor.execute("SELECT id, name, short_name "
|
||||
cursor.execute("SELECT id "
|
||||
"FROM enterprise where id=%s;", (ent_id,))
|
||||
ent_id, name, short_name = cursor.fetchone()
|
||||
ent_id = cursor.fetchone()[0]
|
||||
self._connection.commit()
|
||||
return Enterprise(
|
||||
ent_id,
|
||||
self.get_activities_by_enterprpise(ent_id),
|
||||
self.get_divisions_by_enterprise(ent_id),
|
||||
self.get_contact_info_by_enterprise(ent_id),
|
||||
name,
|
||||
short_name
|
||||
self.get_contact_info_by_enterprise(ent_id)
|
||||
)
|
||||
|
||||
def get_activities_by_enterprpise(self, ent_id: int) -> List[Activity]:
|
||||
@ -66,7 +74,7 @@ class DataProvider:
|
||||
"SELECT id from division where enterprise = %s", (ent_id,)
|
||||
)
|
||||
self._connection.commit()
|
||||
return [Division(div_id,
|
||||
return [Division(div_id[0],
|
||||
self.get_contact_info_by_division(div_id),
|
||||
self.get_activities_by_division(div_id)
|
||||
) for div_id in cur.fetchall()]
|
||||
@ -74,58 +82,68 @@ class DataProvider:
|
||||
def get_contact_info_by_enterprise(self,
|
||||
ent_id: int) -> ContactInfo:
|
||||
with self._connection.cursor() as cur:
|
||||
cur.execute("SELECT id, email from contact_info "
|
||||
"where id = (SELECT contact_info "
|
||||
"FROM enterprise WHERE enterprise.id = %s)",
|
||||
(ent_id,))
|
||||
con_id, email = cur.fetchone()
|
||||
cur.execute(
|
||||
"SELECT id, email, name, short_name, code from contact_info "
|
||||
"where id = (SELECT contact_info "
|
||||
"FROM enterprise WHERE enterprise.id = %s)",
|
||||
(ent_id,))
|
||||
con_id, email, name, short_name, code = cur.fetchone()
|
||||
self._connection.commit()
|
||||
return ContactInfo(
|
||||
con_id,
|
||||
email,
|
||||
self.get_phone_numbers_by_contact(con_id),
|
||||
self.get_head_by_contact(con_id),
|
||||
self.get_locations_by_contact(con_id)
|
||||
self.get_locations_by_contact(con_id),
|
||||
name,
|
||||
short_name,
|
||||
code
|
||||
)
|
||||
|
||||
def get_contact_info_by_division(self,
|
||||
div_id: int) -> ContactInfo:
|
||||
with self._connection.cursor() as cur:
|
||||
cur.execute("SELECT id, email "
|
||||
cur.execute("SELECT id, email, name, short_name, code "
|
||||
"from contact_info where id = (SELECT contact_info "
|
||||
"FROM division WHERE division.id = %s)",
|
||||
(div_id,))
|
||||
con_id, email = cur.fetchone()
|
||||
con_id, email, name, short_name, code = cur.fetchone()
|
||||
self._connection.commit()
|
||||
return ContactInfo(
|
||||
con_id,
|
||||
email,
|
||||
self.get_phone_numbers_by_contact(con_id),
|
||||
self.get_head_by_contact(con_id),
|
||||
self.get_locations_by_contact(con_id)
|
||||
self.get_locations_by_contact(con_id),
|
||||
name,
|
||||
short_name,
|
||||
code
|
||||
)
|
||||
|
||||
def get_phone_numbers_by_contact(self, con_id: int) -> List[PhoneNumber]:
|
||||
with self._connection.cursor() as cur:
|
||||
cur.execute("SELECT id, date_of_start, date_of_end "
|
||||
cur.execute("SELECT id, date_of_start, date_of_end, number "
|
||||
"FROM phone_number where contact_info = %s",
|
||||
(con_id,))
|
||||
self._connection.commit()
|
||||
return [PhoneNumber(
|
||||
ph_id,
|
||||
date_start,
|
||||
date_end
|
||||
) for ph_id, date_start, date_end in cur.fetchall()]
|
||||
date_end,
|
||||
number
|
||||
) for ph_id, date_start, date_end, number in cur.fetchall()]
|
||||
|
||||
def get_head_by_contact(self, con_id: int) -> List[Head]:
|
||||
with self._connection.cursor() as cur:
|
||||
cur.execute("SELECT id, date_of_start, date_of_end "
|
||||
"FROM head WHERE contact_info = %s",
|
||||
(con_id,))
|
||||
cur.fetchall()
|
||||
cur.execute(
|
||||
"SELECT id, date_of_start, date_of_end, first_name, second_name, lst_name "
|
||||
"FROM head WHERE contact_info = %s",
|
||||
(con_id,))
|
||||
self._connection.commit()
|
||||
return [Head(id, date_start, date_end) for id, date_start, date_end
|
||||
in cur]
|
||||
return [Head(id, date_start, date_end, first_name, second_name,
|
||||
last_name) for
|
||||
id, date_start, date_end, first_name, second_name, last_name
|
||||
in cur.fetchall()]
|
||||
|
||||
def get_locations_by_contact(self, con_id: int) -> List[Location]:
|
||||
with self._connection.cursor() as cur:
|
||||
@ -155,8 +173,10 @@ class DataProvider:
|
||||
|
||||
def create_contact_info(self, info: ContactInfo):
|
||||
with self._connection.cursor() as cur:
|
||||
cur.execute("INSERT INTO contact_info (email) VALUES (%s) "
|
||||
"RETURNING id", (info.email, ))
|
||||
cur.execute(
|
||||
"INSERT INTO contact_info (email, name, short_name, code) VALUES (%s, %s, %s, %s) "
|
||||
"RETURNING id",
|
||||
(info.email, info.name, info.short_name, info.code))
|
||||
info.id = cur.fetchone()[0]
|
||||
self._connection.commit()
|
||||
for head in info.head:
|
||||
@ -169,9 +189,10 @@ class DataProvider:
|
||||
def create_head(self, head: Head, con_id: int):
|
||||
with self._connection.cursor() as cur:
|
||||
cur.execute("INSERT INTO head "
|
||||
"(date_of_start, date_of_end, contact_info) "
|
||||
"VALUES (%s, %s, %s) RETURNING id",
|
||||
(head.date_of_start, head.date_of_end, con_id))
|
||||
"(date_of_start, date_of_end, contact_info, first_name, second_name, lst_name) "
|
||||
"VALUES (%s, %s, %s, %s, %s, %s) RETURNING id",
|
||||
(head.date_of_start, head.date_of_end, con_id,
|
||||
head.first_name, head.second_name, head.last_name))
|
||||
head.id = cur.fetchone()[0]
|
||||
self._connection.commit()
|
||||
|
||||
@ -188,9 +209,10 @@ class DataProvider:
|
||||
def create_phone_number(self, phone: PhoneNumber, con_id: int):
|
||||
with self._connection.cursor() as cur:
|
||||
cur.execute("INSERT INTO phone_number "
|
||||
"(contact_info, date_of_start, date_of_end) VALUES "
|
||||
"(%s, %s, %s) RETURNING id",
|
||||
(con_id, phone.date_of_start, phone.date_of_end))
|
||||
"(contact_info, date_of_start, date_of_end, number) VALUES "
|
||||
"(%s, %s, %s, %s) RETURNING id",
|
||||
(con_id, phone.date_of_start, phone.date_of_end,
|
||||
phone.number))
|
||||
phone.id = cur.fetchone()[0]
|
||||
self._connection.commit()
|
||||
|
||||
@ -209,11 +231,9 @@ class DataProvider:
|
||||
with self._connection.cursor() as cur:
|
||||
self.create_contact_info(enterprise.contact_info)
|
||||
cur.execute("INSERT INTO enterprise "
|
||||
"(name, short_name, contact_info) "
|
||||
"VALUES (%s, %s, %s) RETURNING id",
|
||||
(enterprise.name,
|
||||
enterprise.short_name,
|
||||
enterprise.contact_info.id))
|
||||
"(contact_info) "
|
||||
"VALUES (%s) RETURNING id",
|
||||
(enterprise.contact_info.id,))
|
||||
enterprise.id = cur.fetchone()[0]
|
||||
for act in enterprise.activities:
|
||||
self.add_activity_to_enterprise(enterprise, act)
|
||||
@ -224,7 +244,7 @@ class DataProvider:
|
||||
def create_activity(self, activity: Activity):
|
||||
with self._connection.cursor() as cur:
|
||||
cur.execute("INSERT INTO activity (name) VALUES (%s) RETURNING id",
|
||||
(activity.name, ))
|
||||
(activity.name,))
|
||||
activity.id = cur.fetchone()[0]
|
||||
self._connection.commit()
|
||||
|
||||
@ -241,11 +261,62 @@ class DataProvider:
|
||||
"VALUES (%s, %s)", (activity.id, enterprise.id))
|
||||
self._connection.commit()
|
||||
|
||||
def get_activities(self):
|
||||
def get_activities(self) -> List[Activity]:
|
||||
with self._connection.cursor() as cur:
|
||||
cur.execute("SELECT id, name FROM activity")
|
||||
res = [Activity(id, name) for id, name in cur.fetchall()]
|
||||
self._connection.commit()
|
||||
return res
|
||||
|
||||
def get_activitiy_by_id(self, act_id: int) -> Activity:
|
||||
with self._connection.cursor() as cur:
|
||||
cur.execute("SELECT id, name FROM activity where id = %s",
|
||||
(act_id,))
|
||||
id, name = cur.fetchone()
|
||||
res = Activity(id, name)
|
||||
self._connection.commit()
|
||||
return res
|
||||
|
||||
def division_count_with_no_email(self) -> int:
|
||||
with self._connection.cursor() as cur:
|
||||
cur.execute("SELECT COUNT(*) FROM division "
|
||||
"INNER JOIN contact_info ci on "
|
||||
"division.contact_info = ci.id WHERE email = ''")
|
||||
res = cur.fetchone()[0]
|
||||
self._connection.commit()
|
||||
return res
|
||||
|
||||
def division_phones_of_enterprise(self, ent_id: int, date_need: date):
|
||||
with self._connection.cursor() as cur:
|
||||
cur.execute(
|
||||
"SELECT name, number FROM phone_number inner join "
|
||||
"contact_info ci on phone_number.contact_info = ci.id "
|
||||
"INNER JOIN division d on ci.id = d.contact_info WHERE "
|
||||
"(date_of_end >= %s or date_of_end is null) and"
|
||||
" date_of_start <= %s and enterprise = %s",
|
||||
(date_need, date_need, ent_id))
|
||||
res = cur.fetchall()
|
||||
self._connection.commit()
|
||||
return res
|
||||
|
||||
def get_division_by_id(self, div_id: int):
|
||||
return Division(
|
||||
div_id,
|
||||
self.get_contact_info_by_division(div_id),
|
||||
self.get_activities_by_division(div_id)
|
||||
)
|
||||
|
||||
def max_heads_change(self, date_start: date, date_end: date):
|
||||
with self._connection.cursor() as cur:
|
||||
cur.execute(
|
||||
"SELECT name, COUNT(*) as heads_count FROM head INNER JOIN "
|
||||
"contact_info ci on head.contact_info = ci.id INNER JOIN "
|
||||
"division d on ci.id = d.contact_info WHERE (date_of_end <= %s"
|
||||
" or date_of_end is null) and date_of_start >= %s "
|
||||
"GROUP BY d.id, name ORDER BY heads_count DESC LIMIT 1",
|
||||
(date_end, date_start))
|
||||
res = cur.fetchone()
|
||||
if res is not None:
|
||||
res = res[0]
|
||||
self._connection.commit()
|
||||
return res
|
||||
|
||||
28
data/migrate.py
Normal file
28
data/migrate.py
Normal file
@ -0,0 +1,28 @@
|
||||
from argparse import ArgumentParser
|
||||
|
||||
from data.data_provider import DataProvider
|
||||
from settings import DB_CONN
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = ArgumentParser(description='Migrate data for database')
|
||||
parser.add_argument('--force', '-f',
|
||||
help='Force migrating. Deletes all tables!',
|
||||
action='store_true')
|
||||
args = parser.parse_args()
|
||||
if args.force:
|
||||
print('forcing migrate')
|
||||
try:
|
||||
dp = DataProvider(DB_CONN)
|
||||
except:
|
||||
print('problems with connection')
|
||||
exit(1)
|
||||
if args.force:
|
||||
print('erasing tables')
|
||||
dp.delete_tables()
|
||||
try:
|
||||
print('migrating data')
|
||||
dp.migrate()
|
||||
print('migrated successfully')
|
||||
except:
|
||||
print('migration failed')
|
||||
exit(1)
|
||||
@ -9,17 +9,13 @@ class Enterprise:
|
||||
_id: Optional[int],
|
||||
activities: List['Activity'],
|
||||
divisions: List['Division'],
|
||||
contact_info: 'ContactInfo',
|
||||
name: str,
|
||||
short_name: str
|
||||
contact_info: 'ContactInfo'
|
||||
|
||||
):
|
||||
self.id = _id
|
||||
self.activities = activities
|
||||
self.divisions = divisions
|
||||
self.contact_info = contact_info
|
||||
self.name = name
|
||||
self.short_name = short_name
|
||||
|
||||
|
||||
@dataclass
|
||||
@ -27,6 +23,7 @@ class PhoneNumber:
|
||||
id: Optional[int]
|
||||
date_of_start: date
|
||||
date_of_end: Optional[date]
|
||||
number: str
|
||||
|
||||
|
||||
class ContactInfo:
|
||||
@ -34,13 +31,19 @@ class ContactInfo:
|
||||
email: str,
|
||||
phone_numbers: List[PhoneNumber],
|
||||
head: List['Head'],
|
||||
locations: List['Location']
|
||||
locations: List['Location'],
|
||||
name: str,
|
||||
short_name: str,
|
||||
code: str
|
||||
):
|
||||
self.id = _id
|
||||
self.phone_numbers = phone_numbers
|
||||
self.head = head
|
||||
self.email = email
|
||||
self.locations = locations
|
||||
self.name = name
|
||||
self.short_name = short_name
|
||||
self.code = code
|
||||
|
||||
|
||||
@dataclass
|
||||
@ -61,6 +64,9 @@ class Head:
|
||||
id: Optional[int]
|
||||
date_of_start: date
|
||||
date_of_end: Optional[date]
|
||||
first_name: str
|
||||
second_name: Optional[str]
|
||||
last_name: str
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
@ -20,7 +20,8 @@ class TestDataProvider(TestCase):
|
||||
loc = Location(None, "Russia", "Orenburg", "Elovaya", "16", "259A",
|
||||
date(2010, 11, 28), None)
|
||||
num = PhoneNumber(None, date(2018, 10, 10), None)
|
||||
cont = ContactInfo(None, "hello@gmail.com", [num], [head], [loc])
|
||||
cont = ContactInfo(None, "hello@gmail.com", [num], [head], [loc],
|
||||
'name', 'short_name', 'code')
|
||||
self.dp.create_contact_info(cont)
|
||||
print(f"ContactInfo id is {cont.id}")
|
||||
self.assertIsNotNone(cont.id)
|
||||
@ -36,15 +37,17 @@ class TestDataProvider(TestCase):
|
||||
loc = Location(None, "Russia", "Orenburg", "Elovaya", "16", "259A",
|
||||
date(2010, 11, 28), None)
|
||||
num = PhoneNumber(None, date(2018, 10, 10), None)
|
||||
cont = ContactInfo(None, "hello@gmail.com", [num], [head], [loc])
|
||||
cont = ContactInfo(None, "hello@gmail.com", [num], [head], [loc],
|
||||
'name', 'short_name', 'code')
|
||||
head_div = Head(None, date(1998, 10, 11), None)
|
||||
loc_div = Location(None, "Russia", "Orenburg", "Elovaya", "16", "259A",
|
||||
date(2010, 11, 28), None)
|
||||
date(2010, 11, 28), None)
|
||||
num_div = PhoneNumber(None, date(2018, 10, 10), None)
|
||||
cont_div = ContactInfo(None, "eeeeee", [num_div],
|
||||
[head_div], [loc_div])
|
||||
[head_div], [loc_div], 'name', 'short_name',
|
||||
'code')
|
||||
div = Division(None, cont_div, [])
|
||||
enterprise = Enterprise(None, [], [div], cont, "hello", "world")
|
||||
enterprise = Enterprise(None, [], [div], cont)
|
||||
self.dp.create_enterprise(enterprise)
|
||||
self.assertIsNotNone(div.id)
|
||||
self.assertIsNotNone(enterprise.id)
|
||||
@ -62,15 +65,17 @@ class TestDataProvider(TestCase):
|
||||
loc = Location(None, "Russia", "Orenburg", "Elovaya", "16", "259A",
|
||||
date(2010, 11, 28), None)
|
||||
num = PhoneNumber(None, date(2018, 10, 10), None)
|
||||
cont = ContactInfo(None, "hello@gmail.com", [num], [head], [loc])
|
||||
cont = ContactInfo(None, "hello@gmail.com", [num], [head], [loc],
|
||||
'name', 'short_name', 'code')
|
||||
head_div = Head(None, date(1998, 10, 11), None)
|
||||
loc_div = Location(None, "Russia", "Orenburg", "Elovaya", "16", "259A",
|
||||
date(2010, 11, 28), None)
|
||||
date(2010, 11, 28), None)
|
||||
num_div = PhoneNumber(None, date(2018, 10, 10), None)
|
||||
cont_div = ContactInfo(None, "eeeeee", [num_div],
|
||||
[head_div], [loc_div])
|
||||
[head_div], [loc_div], 'name', 'short_name',
|
||||
'code')
|
||||
div = Division(None, cont_div, [act])
|
||||
enterprise = Enterprise(None, [act], [div], cont, "hello", "world")
|
||||
enterprise = Enterprise(None, [act], [div], cont)
|
||||
self.dp.create_enterprise(enterprise)
|
||||
test_enterprise = self.dp.get_enterprise_by_id(enterprise.id)
|
||||
self.assertGreater(len(test_enterprise.activities), 0)
|
||||
|
||||
Reference in New Issue
Block a user