-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #42 from Vanderhoof/develop
Develop into master
- Loading branch information
Showing
105 changed files
with
3,308 additions
and
2,743 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# Arbitrary Properties | ||
|
||
Since 1.1.0 PyDBML supports arbitrary properties in Table and Column definitions. Arbitrary properties is a dictionary of key-value pairs that can be added to any Table or Column manually, or parsed from a DBML file. This may be useful for extending the standard DBML syntax or keeping additional information in the schema. | ||
|
||
Arbitrary properties are turned off by default. To enable parsing properties in DBML files, set `allow_properties` argument to `True` in the parser call. To enable rendering properties in the output DBML of an existing database, set `allow_properties` database attribute to `True`. | ||
|
||
## Properties in DBML | ||
|
||
In a DBML file arbitrary properties are defined like this: | ||
|
||
```python | ||
>>> dbml_str = ''' | ||
... Table "products" { | ||
... "id" integer | ||
... "name" varchar [col_prop: 'some value'] | ||
... table_prop: 'another value' | ||
... }''' | ||
|
||
``` | ||
|
||
In this example we've added a property `col_prop` to the column `name` and a property `table_prop` to the table `products`. Note that property values must me single-quoted strings. Multiline strings (with `'''`) are supported. | ||
|
||
Now let's parse this DBML string: | ||
|
||
```python | ||
>>> from pydbml import PyDBML | ||
>>> mydb = PyDBML(dbml_str, allow_properties=True) | ||
>>> mydb.tables[0].columns[1].properties | ||
{'col_prop': 'some value'} | ||
>>> mydb.tables[0].properties | ||
{'table_prop': 'another value'} | ||
|
||
``` | ||
|
||
The `allow_properties=True` argument is crucial here. Without it, the parser will raise syntax errors. | ||
|
||
## Rendering Properties | ||
|
||
To render properties in the output DBML, set `allow_properties` attribute of the Database object to `True`. If you parsed the DBML with `allow_properties=True`, the result database will already have this attribute set to `True`. | ||
|
||
We will reuse the `mydb` database from the previous example: | ||
|
||
```python | ||
>>> print(mydb.allow_properties) | ||
True | ||
|
||
``` | ||
|
||
Let's set a new property on the table and render the DBML: | ||
|
||
```python | ||
>>> mydb.tables[0].properties['new_prop'] = 'Multiline\nproperty\nvalue' | ||
>>> print(mydb.dbml) | ||
Table "products" { | ||
"id" integer | ||
"name" varchar [col_prop: 'some value'] | ||
<BLANKLINE> | ||
table_prop: 'another value' | ||
new_prop: ''' | ||
Multiline | ||
property | ||
value''' | ||
} | ||
|
||
``` | ||
|
||
As you see, properties are also rendered in the output DBML correctly. But if `allow_properties` is set to `False`, the properties will be ignored: | ||
|
||
```python | ||
>>> mydb.allow_properties = False | ||
>>> print(mydb.dbml) | ||
Table "products" { | ||
"id" integer | ||
"name" varchar | ||
} | ||
|
||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,3 @@ | ||
from . import classes | ||
from . import _classes | ||
from .parser import PyDBML | ||
from .database import Database | ||
from pydbml.constants import MANY_TO_ONE | ||
from pydbml.constants import ONE_TO_MANY | ||
from pydbml.constants import ONE_TO_ONE |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
from typing import List, Dict | ||
from typing import Optional | ||
from typing import TYPE_CHECKING | ||
from typing import Union | ||
|
||
from pydbml.exceptions import TableNotFoundError | ||
from .base import SQLObject, DBMLObject | ||
from .enum import Enum | ||
from .expression import Expression | ||
from .note import Note | ||
|
||
if TYPE_CHECKING: # pragma: no cover | ||
from .table import Table | ||
from .reference import Reference | ||
|
||
|
||
class Column(SQLObject, DBMLObject): | ||
'''Class representing table column.''' | ||
|
||
required_attributes = ('name', 'type') | ||
dont_compare_fields = ('table',) | ||
|
||
def __init__(self, | ||
name: str, | ||
type: Union[str, Enum], | ||
unique: bool = False, | ||
not_null: bool = False, | ||
pk: bool = False, | ||
autoinc: bool = False, | ||
default: Optional[Union[str, int, bool, float, Expression]] = None, | ||
note: Optional[Union[Note, str]] = None, | ||
comment: Optional[str] = None, | ||
properties: Union[Dict[str, str], None] = None | ||
): | ||
self.name = name | ||
self.type = type | ||
self.unique = unique | ||
self.not_null = not_null | ||
self.pk = pk | ||
self.autoinc = autoinc | ||
self.comment = comment | ||
self.note = Note(note) | ||
self.properties = properties if properties else {} | ||
|
||
self.default = default | ||
self.table: Optional['Table'] = None | ||
|
||
def __eq__(self, other: object) -> bool: | ||
if other is self: | ||
return True | ||
if not isinstance(other, self.__class__): | ||
return False | ||
self_table = self.table.full_name if self.table else None | ||
other_table = other.table.full_name if other.table else None | ||
if self_table != other_table: | ||
return False | ||
return super().__eq__(other) | ||
|
||
@property | ||
def note(self): | ||
return self._note | ||
|
||
@note.setter | ||
def note(self, val: Note) -> None: | ||
self._note = val | ||
val.parent = self | ||
|
||
def get_refs(self) -> List['Reference']: | ||
''' | ||
get all references related to this column (where this col is col1 in) | ||
''' | ||
if not self.table: | ||
raise TableNotFoundError('Table for the column is not set') | ||
return [ref for ref in self.table.get_refs() if self in ref.col1] | ||
|
||
@property | ||
def database(self): | ||
return self.table.database if self.table else None | ||
|
||
def __repr__(self): | ||
''' | ||
>>> Column('name', 'VARCHAR2') | ||
<Column 'name', 'VARCHAR2'> | ||
''' | ||
type_name = self.type if isinstance(self.type, str) else self.type.name | ||
return f'<Column {self.name!r}, {type_name!r}>' | ||
|
||
def __str__(self): | ||
''' | ||
>>> print(Column('name', 'VARCHAR2')) | ||
name[VARCHAR2] | ||
''' | ||
|
||
return f'{self.name}[{self.type}]' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.