https://github.com/finndersen/sqlserver-schema-manager
A library for programmatically managing the schema of a SQLServer Database
https://github.com/finndersen/sqlserver-schema-manager
Last synced: 7 days ago
JSON representation
A library for programmatically managing the schema of a SQLServer Database
- Host: GitHub
- URL: https://github.com/finndersen/sqlserver-schema-manager
- Owner: Finndersen
- License: apache-2.0
- Created: 2024-10-18T22:25:01.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-10-30T13:13:01.000Z (over 1 year ago)
- Last Synced: 2025-11-30T22:12:31.202Z (7 months ago)
- Language: Python
- Size: 43.9 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# SQLServer Schema Manager
## Introduction
A library for programmatically managing the schema of a SQLServer Database, with two modes of operation:
* Declare the entire structure of a SQLServer instance in code, and apply it to a target database (automatically determines and executes all diff changes required).
* Programmatically/interactively inspect the structure of an existing SQLServer instance, and make changes using code instead of SQL.
It can be used in tandem with other tools that manage a DB schema (e.g. an ORM), to manage the features that they do not support (e.g. the database itself, users, partitioning and compression).
Important note: This is a tool I developed for my own purposes many years ago, it has a lot of functionality and works quite well but is not recommended to be used in a production context without some further work.
## Installation
This library is not packed or included in any package manager, so you will need to clone the repository and manually include it in your project.
## Usage
### Declarative Mode
1. Define your desired server schema:
```python
from sssm.db_entities.declared import Server, Database, Table, Index, ForeignKey, Login, IntegerColumn, VarcharColumn, DateColumn, IdentityColumn, FloatColumn, User
# Currently does not support creating Logins, so these will need to correspond to ones already existing on the server
admin_login = Login('admin')
writer_login = Login('writer', server_roles=['bulkadmin'])
reader_login = Login('reader')
server = Server(
databases=[
Database(
name='MyDatabase',
owner=admin_login.name,
data_file_dir=r'D:\MSSQL\DATA',
log_file_dir=r'D:\MSSQL\LOG',
data_size=100_000,
# Can also specify schema name if desired, otherwise default "db" is used
tables=[
Table(
name='Person',
columns=[
IdentityColumn(name='ID', primary_key=True),
VarcharColumn(name='Name', char_max_len=255),
DateColumn(name='DateOfBirth'),
IntegerColumn(name='HeightCM'),
FloatColumn(name='WeightKG'),
IntegerColumn(name='AddressID'),
],
indexes=[
Index(name='IX_MyTable_Name', columns=['Name'], compression='PAGE'),
],
foreign_keys=[
ForeignKey(column='AddressID', foreign_table='Address', foreign_column='ID'),
],
),
Table(
name='Address',
columns=[
IdentityColumn(name='ID', primary_key=True),
IntegerColumn(name='StreetNumber'),
VarcharColumn(name='StreetName', char_max_len=255),
VarcharColumn(name='PostCode', char_max_len=6),
VarcharColumn(name='State', char_max_len=100),
VarcharColumn(name='Country', char_max_len=255),
],
),
],
users=[
User.for_login(admin_login),
User.for_login(writer_login, db_roles=['db_datawriter']),
User.for_login(reader_login, db_roles=['db_datareader']),
]
)
],
logins=[
admin_login,
writer_login,
reader_login,
],
)
```
Apply the schema to a target database:
```python
import pyodbc
from sssm.align import align_server
from .schema import server
# Create connection using an admin login
connection = pyodbc.connect(...)
align_server(connection.cursor(), server)
```
This should be run from an interactive Python session or script, as it will prompt for confirmation before applying destructive changes.
### Inspection Mode
Inspecting an existing server schema can be done either programmatically or in an interactive shell:
```python
>>> import pyodbc
>>> from sssm.db_entities.reflected import ReflectedServer
# Create connection using an admin login
>>> connection = pyodbc.connect(...)
>>> server = ReflectedServer.from_cursor(connection.cursor())
>>> database = server.get_current_database() # Get database specified in connection
>>> person_table = database.get_table('Person') # Get table by name
>>> person_table.get_compression()
'NONE'
>>> person_table.set_compression('PAGE') # Rebuild table with PAGE compression
>>> person_table.get_compression()
'PAGE'
>>> person_table.clear_data()
```
## Features
### Supported Database Entities
Supports managing the following database entities and attributes:
* Server Logins (not creating)
* Server roles
* Databases
* Owner
* Data and log file directories
* Data size
* Recovery model
* Schemas
* Tables
* Users
* Login name
* DB roles
* Columns
* Data types
* Max length
* Nullable
* Datetime/Numeric precision
* Indexes / Primary keys
* Columns
* Clustered
* Unique
* Included columns
* Compression
* Foreign keys
* Source and target columns
* Partitions
* Partition column
### Other Features
* Use `ignore_extra_children` on a declared object if you want to ignore (not delete) any extra existing children when aligning it to a reflected object.
* Set `old_name` on a declared object to identify and rename the existing object when aligning it to a database.