Guest User

Untitled

a guest
Jan 17th, 2019
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.66 KB | None | 0 0
  1. """Database Processing Script
  2.  
  3. This script:
  4.  
  5. a - can drop a database
  6. b - can build a database
  7. c - can call plugins, mainly for the purpose of inserting data into database.
  8.  
  9. Usage:
  10.  
  11. # Drop the dev database
  12. python dbloader.py --drop-db DEV
  13.  
  14. # Create and seed the dev database
  15. python dbloader.py --build DEV
  16.  
  17. # Run the sample plugin
  18. python dbloader.py --plugin=sample DEV
  19.  
  20. Staging Environments:
  21.  
  22. Look in appconfig.py to see them:
  23. --------------------------------
  24. * LOCAL
  25. * DEV
  26. * STAGING
  27. * QA
  28. * PROD
  29. """
  30.  
  31. import logging
  32. import random
  33. import uuid
  34. from datetime import datetime, timedelta
  35.  
  36. from plumbum import cli, local
  37. from reahl.component.config import StoredConfiguration
  38. from reahl.component.context import ExecutionContext
  39. from reahl.domain.systemaccountmodel import EmailAndPasswordSystemAccount
  40. from reahl.sqlalchemysupport import Session, metadata
  41.  
  42.  
  43. import datatablebootstrap
  44. from appconfig import App
  45. from datatablebootstrap import Ability, Check, UserAbility
  46.  
  47. APP = App()
  48. LOGGER = logging.getLogger(__name__)
  49.  
  50. ability_labels = 'Inactive SearchChecks EditChecks CreateUser'.split()
  51.  
  52.  
  53. def new_account(email='admin@site.org'):
  54. password = 'topsecret'
  55. account = EmailAndPasswordSystemAccount(email=email)
  56. Session.add(account)
  57. account.set_new_password(account.email, password)
  58. account.activate()
  59. return account
  60.  
  61.  
  62. def new_check(bank_account_id, checkno):
  63. day = random.randint(1, 25)
  64. month = 11
  65. year = 2018
  66. issue_date = datetime(year, month, day)
  67. cleared_date = issue_date + timedelta(days=random.randint(5, 20))
  68. tid = str(random.randint(1545, 678678))
  69.  
  70. def random_check_amount():
  71. return random.randint(5000, 200000)
  72.  
  73. if random.randint(0, 100) < 50:
  74. amount = amount_cleared = random_check_amount()
  75. else:
  76. amount = random_check_amount()
  77. amount_cleared = random_check_amount()
  78.  
  79. _ = Check(bank_account_id=bank_account_id, check_number=checkno,
  80. amount=amount, amount_cleared=amount_cleared,
  81. date_issued=issue_date, date_cleared=cleared_date,
  82. transaction_id=tid, status_id=random.randint(0, 9),
  83. issue_type_id=random.randint(0, 1),
  84. )
  85. Session.add(_)
  86. return _
  87.  
  88.  
  89. def dummy_data():
  90. ability = dict()
  91. for _ in ability_labels:
  92. ability[_] = datatablebootstrap.Ability(label=_)
  93.  
  94. LOGGER.warning(f"Ability dict={ability}")
  95.  
  96. account_ability = dict()
  97.  
  98. # inactive
  99. # viewer
  100. # editor
  101. # security
  102. # admin
  103.  
  104. account_ability['admin'] = 'EditChecks CreateUser'.split()
  105. account_ability['security'] = ['CreateUser']
  106. account_ability['editor'] = ['EditChecks']
  107. account_ability['viewer'] = ['SearchChecks']
  108. account_ability['batchuser'] = ['Inactive']
  109.  
  110. for account, abilities in account_ability.items():
  111. acct = new_account(email=f"{account}@ofiglobal.com")
  112. for ability in abilities:
  113. _ability = Session.query(Ability).filter_by(label=ability).one()
  114. Session.add(UserAbility(account_id=acct.id, ability_id=_ability.id))
  115.  
  116. import random
  117. amount = 10
  118. check_numbers = random.sample(range(10, 50), amount)
  119.  
  120. for check_number in check_numbers:
  121. bank_account = random_table_row(datatablebootstrap.BankAccount)
  122. new_check(bank_account.id, check_number)
  123.  
  124.  
  125. def random_table_row(t):
  126. import random
  127. rand = random.randrange(0, Session.query(t).count())
  128. row = Session.query(t)[rand]
  129. return row
  130.  
  131.  
  132. def id_label_table_to_dict(t, label_column_name='label'):
  133. _ = dict()
  134.  
  135. for row in Session.query(t).all():
  136. i = getattr(row, label_column_name)
  137. _[i] = row.id
  138.  
  139. return _
  140.  
  141.  
  142. def populate(table, values, label_column_name='label'):
  143. for i, value in enumerate(values.splitlines()):
  144. value = value.strip()
  145. row_object = table(id=i)
  146. setattr(row_object, label_column_name, value)
  147. Session.add(row_object)
  148.  
  149. Session.commit()
  150.  
  151.  
  152. def populate_check_issue_types():
  153. data = """System-Generated
  154. Manual
  155. Paid
  156. """
  157.  
  158. populate(datatablebootstrap.CheckIssueType, data, label_column_name='issue_type')
  159.  
  160.  
  161. def populate_plan_types():
  162. data = """529
  163. M52
  164. OP
  165. N9
  166. I29
  167. T29
  168. """
  169.  
  170. populate(datatablebootstrap.CheckPlan, data, label_column_name='plan_type')
  171.  
  172.  
  173. def populate_bank_accounts(hide_account_number=False):
  174. data = """PC529
  175. NM529
  176. """
  177. plan_id = id_label_table_to_dict(datatablebootstrap.CheckPlan, label_column_name='plan_type')
  178. data = """NM 111 SHRHOLDR
  179. NM 111 SHRHOLDR
  180. NM 111 12B1
  181. NM 111 COMSN
  182. PC 111 SHRHOLDR
  183. PC 111 SHRHOLDR
  184. """
  185.  
  186. for i, line in enumerate(data.splitlines()):
  187. LOGGER.warning(f"Processing {line}")
  188. plan_label, account_number, account_type = line.split()
  189. plan_label += '529'
  190. account_number = account_number
  191. if hide_account_number:
  192. account_number = account_number[0:len(account_number)-1]
  193. Session.add(datatablebootstrap.BankAccount(
  194. plan_id=plan_id[plan_label],
  195. account_number=account_number,
  196. account_type=account_type))
  197.  
  198. Session.commit()
  199.  
  200. def populate_check_statuses():
  201. data = """OUTSTANDING
  202. GIRL YOU KNOCK ME OUT
  203. """
  204.  
  205. populate(datatablebootstrap.CheckStatus, data, label_column_name='status')
  206.  
  207.  
  208. def populate_abilities():
  209. description = {
  210. 'Inactive': "not enabled for any actions.",
  211. 'SearchChecks': "are able to search for and view checks.",
  212. 'EditChecks': "are able to search for and edit checks.",
  213. 'CreateUser': "are able to create new users and set permission levels."
  214. }
  215. for ability in ability_labels:
  216. Session.add(datatablebootstrap.Ability(label=ability, description=description[ability]))
  217.  
  218.  
  219. class MyApp(cli.Application):
  220. # PROGNAME = "db-setup"
  221. VERSION = "7.3"
  222.  
  223. plugin = cli.SwitchAttr(
  224. "--plugin", str, default=None,
  225. help="load a plugin file from db/plugin/ to execute against a built database. Ex: python dbloader.py --plugin=sample"
  226. )
  227. build = cli.Flag('build', help='Create the database and populate with seed data.')
  228. drop_db = cli.Flag('drop-db', help="Drop the database. BE CAREFUL!")
  229. create_db = cli.Flag('create-db', help="Create the database.")
  230. list_stages = cli.Flag('list-stages', help="Show the stages.")
  231. create_tables = cli.Flag('create-tables', help="Create the database tables.")
  232. build_lookups = cli.Flag('build-lookups', help="Populate the lookup tables.")
  233. dummy_data = cli.Flag('dummy-data', help="Add dummy data.")
  234.  
  235. def _drop_db(self):
  236. from sqlalchemy_utils.functions import drop_database
  237. drop_database(self.db_uri)
  238.  
  239. def _create_db(self):
  240. from sqlalchemy_utils.functions import create_database
  241. create_database(self.db_uri)
  242.  
  243. def _list_stages(self):
  244. for name, member in APP.stages:
  245. LOGGER.warning(f"{name, member}")
  246.  
  247. def _create_tables(self):
  248. reahl = local["reahl"]
  249. reahl["createdbtables", APP.stage.path]()
  250.  
  251. def _build_lookups(self, sensitive=False):
  252. LOGGER.warning("Building lookups.")
  253. populate_check_issue_types()
  254. populate_check_statuses()
  255. populate_abilities()
  256. populate_plan_types()
  257. populate_bank_accounts(sensitive)
  258.  
  259. def main(self, stage_str):
  260. # Boilerplate to get SQLAlchemy URL and Reahl convenience to SQLAlchemy
  261.  
  262. APP.set_stage(stage_str)
  263. print("I will now read {0}".format(APP.stage))
  264. ExecutionContext().install()
  265. config = StoredConfiguration(APP.stage.path)
  266. config.configure()
  267.  
  268. self.db_uri = config.reahlsystem.connection_uri
  269. print("DB URI = {}".format(self.db_uri))
  270.  
  271. metadata.bind = self.db_uri
  272.  
  273. # End Boilerplate
  274.  
  275. APP.protect_production()
  276.  
  277. if self.list_stages:
  278. self._list_stages()
  279.  
  280. if self.drop_db:
  281. self._drop_db()
  282.  
  283. if self.create_db or self.build:
  284. self._create_db()
  285.  
  286. if self.create_tables or self.build:
  287. self._create_tables()
  288.  
  289. if self.build_lookups or self.build:
  290. self._build_lookups(sensitive=APP.sensitive)
  291. Session.commit()
  292. #LOGGER.warning("Inspect database and then hit return.")
  293. #input("Inspect database and then hit return.")
  294.  
  295. if self.dummy_data or self.build:
  296. dummy_data()
  297.  
  298. if self.plugin:
  299. import importlib
  300. module = importlib.import_module(f"db.plugin.{self.plugin}", '.')
  301. plugin = module.Plugin(APP)
  302. return_code = plugin.run()
  303. if not return_code:
  304. Session.commit()
  305. return 0
  306. else:
  307. LOGGER.warning(f"Plugin {self.plugin} failed with code {return_code}.")
  308. return return_code
  309.  
  310. Session.commit()
  311.  
  312.  
  313. if __name__ == "__main__":
  314. MyApp.run()
Add Comment
Please, Sign In to add comment