Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1#!/usr/bin/env python 

2# cardinal_pythonlib/sqlalchemy/table_identity.py 

3 

4""" 

5=============================================================================== 

6 

7 Original code copyright (C) 2009-2021 Rudolf Cardinal (rudolf@pobox.com). 

8 

9 This file is part of cardinal_pythonlib. 

10 

11 Licensed under the Apache License, Version 2.0 (the "License"); 

12 you may not use this file except in compliance with the License. 

13 You may obtain a copy of the License at 

14 

15 https://www.apache.org/licenses/LICENSE-2.0 

16 

17 Unless required by applicable law or agreed to in writing, software 

18 distributed under the License is distributed on an "AS IS" BASIS, 

19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

20 See the License for the specific language governing permissions and 

21 limitations under the License. 

22 

23=============================================================================== 

24 

25**Class to refer to database tables either by name or by SQLAlchemy Table 

26object.** 

27 

28""" 

29 

30from sqlalchemy.sql.schema import MetaData, Table 

31 

32from cardinal_pythonlib.logs import get_brace_style_log_with_null_handler 

33 

34log = get_brace_style_log_with_null_handler(__name__) 

35 

36 

37# ============================================================================= 

38# TableIdentity 

39# ============================================================================= 

40 

41class TableIdentity(object): 

42 """ 

43 Convenient way of passing around SQLAlchemy :class:`Table` objects when you 

44 might know either either its name or the :class:`Table` object itself. 

45 """ 

46 def __init__(self, 

47 tablename: str = None, 

48 table: Table = None, 

49 metadata: MetaData = None) -> None: 

50 """ 

51 Initialize with either ``tablename`` or ``table``, not both. 

52 

53 Args: 

54 tablename: string name of the table 

55 table: SQLAlchemy :class:`Table` object 

56 metadata: optional :class:`MetaData` object 

57 """ 

58 assert table is not None or tablename, "No table information provided" 

59 assert not (tablename and table is not None), ( 

60 "Specify either table or tablename, not both") 

61 self._table = table 

62 self._tablename = tablename 

63 self._metadata = metadata 

64 

65 def __str__(self) -> str: 

66 return self.tablename 

67 

68 def __repr__(self) -> str: 

69 return ( 

70 f"TableIdentity(table={self._table!r}, " 

71 f"tablename={self._tablename!r}, metadata={self._metadata!r}" 

72 ) 

73 

74 @property 

75 def table(self) -> Table: 

76 """ 

77 Returns a SQLAlchemy :class:`Table` object. This is either the 

78 :class:`Table` object that was used for initialization, or one that 

79 was constructed from the ``tablename`` plus the ``metadata``. 

80 """ 

81 if self._table is not None: 

82 return self._table 

83 assert self._metadata, ( 

84 "Must specify metadata (in constructor or via set_metadata()/" 

85 "set_metadata_if_none() before you can get a Table from a " 

86 "tablename" 

87 ) 

88 for table in self._metadata.tables.values(): # type: Table 

89 if table.name == self._tablename: 

90 return table 

91 raise ValueError( 

92 f"No table named {self._tablename!r} is present in the metadata") 

93 

94 @property 

95 def tablename(self) -> str: 

96 """ 

97 Returns the string name of the table. 

98 """ 

99 if self._tablename: 

100 return self._tablename 

101 return self.table.name 

102 

103 def set_metadata(self, metadata: MetaData) -> None: 

104 """ 

105 Sets the :class:`MetaData`. 

106 """ 

107 self._metadata = metadata 

108 

109 def set_metadata_if_none(self, metadata: MetaData) -> None: 

110 """ 

111 Sets the :class:`MetaData` unless it was set already. 

112 """ 

113 if self._metadata is None: 

114 self._metadata = metadata