Repository: Dicklesworthstone/sqlalchemy_data_model_visualizer
Branch: main
Commit: f176a92537ab
Files: 8
Total size: 26.6 KB
Directory structure:
gitextract_lqxycubh/
├── .github/
│ └── workflows/
│ └── python-publish.yml
├── .gitignore
├── LICENSE
├── MANIFEST.in
├── README.md
├── requirements.txt
├── setup.py
└── sqlalchemy_data_model_visualizer.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/python-publish.yml
================================================
name: Build and Publish to PyPI
on:
push:
branches:
- main
release:
types: [created]
jobs:
build-and-publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: '3.x'
- name: Build wheel
run: |
python -m pip install --upgrade build
python -m build
- name: Publish to PyPI
if: github.event_name == 'release' && github.event.action == 'created'
run: |
python -m pip install --upgrade twine
twine upload dist/*
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2023 Jeff Emanuel
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: MANIFEST.in
================================================
include requirements.txt
================================================
FILE: README.md
================================================
# SQLAlchemy Data Model Visualizer
## Overview
This Python-based utility generates high-quality, readable visualizations of your SQLAlchemy ORM models with almost no effort. With a focus on clarity and detail, it uses Graphviz to render each model as a directed graph, making it easier to understand the relationships between tables in your database schema.

## Try it Out Easily in Colab:
[](https://colab.research.google.com/drive/1np5kPvDtdhq138eLHOGINYuTUMJo_wrj?usp=sharing)
## Features
- Automatically maps SQLAlchemy ORM models to a directed graph.
- Table-like representation of each model with fields, types, and constraints.
- Export diagrams to SVG format for high-quality viewing and printing using Roboto font.
## Installation with pip and Usage:
```bash
pip install sqlalchemy-data-model-visualizer
# Suppose these are your SQLAlchemy data models defined above in the usual way, or imported from another file:
models = [GenericUser, Customer, ContentCreator, UserSession, FileStorage, ServiceRequest, GenericAuditLog, GenericFeedback, GenericAPIKey, GenericNotification, GenericAPICreditLog, GenericSubscriptionType, GenericSubscription, GenericSubscriptionUsage, GenericBillingInfo]
output_file_name = 'my_data_model_diagram'
generate_data_model_diagram(models, output_file_name)
add_web_font_and_interactivity('my_data_model_diagram.svg', 'my_interactive_data_model_diagram.svg')
```
## Installation from Source
To get started, clone the repository and install the required packages.
```bash
git clone https://github.com/Dicklesworthstone/sqlalchemy_data_model_visualizer.git
cd sqlalchemy_data_model_visualizer
python3 -m venv venv
source venv/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install wheel
pip install -r requirements.txt
```
## Requirements
- Python 3.x
- SQLAlchemy
- Graphviz
- lxml
## Usage
### Generate Data Model Diagram
First, paste in your SQLAlchemy models. A set of fairly complex data models are provided in the code directly as an example-- just replace these with your own from your application.
Then, simply call the `generate_data_model_diagram` function. This will generate an SVG file with the name `my_data_model_diagram.svg`.
## API Documentation
### `generate_data_model_diagram(models, output_file='my_data_model_diagram', add_labels=True)`
- `models`: List of SQLAlchemy models you want to visualize.
- `output_file`: Name of the output SVG file.
- `add_labels`: Set to False to hide labels on the edges between tables
## Contributing
Contributions are welcome! Please open an issue or submit a pull request.
## License
This project is licensed under the MIT License.
---
Thanks for your interest in my open-source project! I hope you find it useful. You might also find my commercial web apps useful, and I would really appreciate it if you checked them out:
**[YoutubeTranscriptOptimizer.com](https://youtubetranscriptoptimizer.com)** makes it really quick and easy to paste in a YouTube video URL and have it automatically generate not just a really accurate direct transcription, but also a super polished and beautifully formatted written document that can be used independently of the video.
The document basically sticks to the same material as discussed in the video, but it sounds much more like a real piece of writing and not just a transcript. It also lets you optionally generate quizzes based on the contents of the document, which can be either multiple choice or short-answer quizzes, and the multiple choice quizzes get turned into interactive HTML files that can be hosted and easily shared, where you can actually take the quiz and it will grade your answers and score the quiz for you.
**[FixMyDocuments.com](https://fixmydocuments.com/)** lets you submit any kind of document— PDFs (including scanned PDFs that require OCR), MS Word and Powerpoint files, images, audio files (mp3, m4a, etc.) —and turn them into highly optimized versions in nice markdown formatting, from which HTML and PDF versions are automatically generated. Once converted, you can also edit them directly in the site using the built-in markdown editor, where it saves a running revision history and regenerates the PDF/HTML versions.
In addition to just getting the optimized version of the document, you can also generate many other kinds of "derived documents" from the original: interactive multiple-choice quizzes that you can actually take and get graded on; slick looking presentation slides as PDF or HTML (using LaTeX and Reveal.js), an in-depth summary, a concept mind map (using Mermaid diagrams) and outline, custom lesson plans where you can select your target audience, a readability analysis and grade-level versions of your original document (good for simplifying concepts for students), Anki Flashcards that you can import directly into the Anki app or use on the site in a nice interface, and more.
================================================
FILE: requirements.txt
================================================
sqlalchemy
graphviz
lxml
================================================
FILE: setup.py
================================================
from setuptools import setup
from pathlib import Path
# Define the directory where this setup.py file is located
here = Path(__file__).parent
# Read the contents of README file
long_description = (here / 'README.md').read_text(encoding='utf-8')
# Read the contents of requirements file
requirements = (here / 'requirements.txt').read_text(encoding='utf-8').splitlines()
setup(
name='sqlalchemy_data_model_visualizer',
version='0.1.3', # Update the version number for new releases
description='A tool to visualize SQLAlchemy data models with Graphviz.',
long_description=long_description,
long_description_content_type='text/markdown',
author='Jeffrey Emanuel',
author_email='jeff@pastel.network',
url='https://github.com/Dicklesworthstone/sqlalchemy_data_model_visualizer',
py_modules=['sqlalchemy_data_model_visualizer'],
install_requires=requirements,
classifiers=[
'Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
],
license='MIT',
keywords='sqlalchemy visualization graphviz data-model',
include_package_data=True, # This tells setuptools to check MANIFEST.in for additional files
)
================================================
FILE: sqlalchemy_data_model_visualizer.py
================================================
from datetime import datetime
from typing import Optional
from enum import Enum
from decimal import Decimal
from sqlalchemy.orm import sessionmaker, declarative_base, relationship
from sqlalchemy import Column, String, DateTime, Integer, Numeric, Boolean, JSON, ForeignKey, LargeBinary, Text, UniqueConstraint, CheckConstraint, text as sql_text
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy import inspect
import graphviz
from lxml import etree
import os
import re
Base = declarative_base()
def generate_data_model_diagram(models, output_file='my_data_model_diagram', add_labels=True, view_diagram=True):
# Initialize graph with more advanced visual settings
dot = graphviz.Digraph(comment='Interactive Data Models', format='svg',
graph_attr={'bgcolor': '#EEEEEE', 'rankdir': 'TB', 'splines': 'spline'},
node_attr={'shape': 'none', 'fontsize': '12', 'fontname': 'Roboto'},
edge_attr={'fontsize': '10', 'fontname': 'Roboto'})
# Iterate through each SQLAlchemy model
for model in models:
insp = inspect(model)
name = insp.class_.__name__
# Create an HTML-like label for each model as a rich table
label = f'''<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD COLSPAN="2" BGCOLOR="#3F51B5"><FONT COLOR="white">{name}</FONT></TD></TR>
'''
for column in insp.columns:
constraints = []
if column.primary_key:
constraints.append("PK")
if column.unique:
constraints.append("Unique")
if column.index:
constraints.append("Index")
constraint_str = ','.join(constraints)
color = "#BBDEFB"
label += f'''<TR>
<TD BGCOLOR="{color}">{column.name}</TD>
<TD BGCOLOR="{color}">{column.type} ({constraint_str})</TD>
</TR>'''
label += '</TABLE>>'
# Create the node with added hyperlink to detailed documentation
dot.node(name, label=label, URL=f"http://{name}_details.html")
# Add relationships with tooltips and advanced styling
for rel in insp.relationships:
target_name = rel.mapper.class_.__name__
tooltip = f"Relation between {name} and {target_name}"
dot.edge(name, target_name, label=rel.key if add_labels else None, tooltip=tooltip, color="#1E88E5", style="dashed")
# Render the graph to a file and open it
dot.render(output_file, view=view_diagram)
def add_web_font_and_interactivity(input_svg_file, output_svg_file):
if not os.path.exists(input_svg_file):
print(f"Error: {input_svg_file} does not exist.")
return
parser = etree.XMLParser(remove_blank_text=True)
try:
tree = etree.parse(input_svg_file, parser)
except etree.XMLSyntaxError as e:
print(f"Error parsing SVG: {e}")
return
root = tree.getroot()
style_elem = etree.Element("style")
style_elem.text = '''
@import url("https://fonts.googleapis.com/css?family=Roboto:400,400i,700,700i");
'''
root.insert(0, style_elem)
for elem in root.iter():
if 'node' in elem.attrib.get('class', ''):
elem.attrib['class'] = 'table-hover'
if 'edge' in elem.attrib.get('class', ''):
source = elem.attrib.get('source')
target = elem.attrib.get('target')
elem.attrib['class'] = f'edge-hover edge-from-{source} edge-to-{target}'
tree.write(output_svg_file, pretty_print=True, xml_declaration=True, encoding='utf-8')
# ________________________________________________________________
# [Insert your sqlalchemy data model classes here below:]
use_demo = 0
if use_demo:
class GenericUser(Base):
__tablename__ = 'generic_user'
email = Column(String, primary_key=True, index=True)
external_id = Column(String, unique=True, nullable=False)
is_active = Column(Boolean, default=True)
is_blocked = Column(Boolean, default=False)
last_ip_address = Column(String, nullable=True)
last_user_agent = Column(String, nullable=True)
last_estimated_location = Column(JSON, nullable=True)
preferences = Column(JSON)
registered_at = Column(DateTime, default=datetime.utcnow, index=True)
last_login = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, index=True)
is_deleted = Column(Boolean, default=False)
deleted_at = Column(DateTime, nullable=True)
customer = relationship("Customer", uselist=False, back_populates="generic_user")
content_creator = relationship("ContentCreator", uselist=False, back_populates="generic_user")
user_sessions = relationship("UserSession", back_populates="generic_user")
audit_logs = relationship("GenericAuditLog", back_populates="actor")
notifications = relationship("GenericNotification", back_populates="recipient")
class Customer(Base):
__tablename__ = 'customer'
email = Column(String, ForeignKey('generic_user.email'), primary_key=True, index=True)
total_purchases = Column(Numeric(10, 10), default=0.0)
generic_user = relationship("GenericUser", back_populates="customer")
service_requests = relationship("ServiceRequest", back_populates="customer")
subscriptions = relationship("GenericSubscription", back_populates="customer")
subscription_usages = relationship("GenericSubscriptionUsage", back_populates="customer")
billing_infos = relationship("GenericBillingInfo", back_populates="customer")
feedbacks_provided = relationship("GenericFeedback", back_populates="customer")
class ContentCreator(Base):
__tablename__ = 'content_creator'
email = Column(String, ForeignKey('generic_user.email'), primary_key=True, index=True)
projects_created = Column(Integer, default=0)
revenue_share = Column(Numeric(10, 10), default=0.7)
total_earned = Column(Numeric(10, 10), default=0.0)
last_project_created_at = Column(DateTime, nullable=True)
generic_user = relationship("GenericUser", back_populates="content_creator")
api_credit_logs = relationship("GenericAPICreditLog", back_populates="content_creator")
api_keys = relationship("GenericAPIKey", back_populates="content_creator")
feedbacks_received = relationship("GenericFeedback", back_populates="content_creator")
class UserSession(Base):
__tablename__ = 'user_session'
id = Column(Integer, primary_key=True)
user_email = Column(String, ForeignKey('generic_user.email'), nullable=False)
session_token = Column(String, unique=True, nullable=False)
expires_at = Column(DateTime, nullable=False)
is_active = Column(Boolean, default=True)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
generic_user = relationship("GenericUser", back_populates="user_sessions")
class FileStorage(Base):
__tablename__ = 'file_storage'
id = Column(Integer, primary_key=True, index=True)
file_data = Column(LargeBinary, nullable=False)
file_type = Column(String, nullable=False)
file_hash = Column(String, nullable=False, unique=True)
upload_date = Column(DateTime, default=datetime.utcnow)
class ServiceRequest(Base):
__tablename__ = 'service_request'
unique_id_for_sharing = Column(String, primary_key=True, index=True)
status = Column(String, CheckConstraint("status IN ('pending', 'completed', 'failed')"), default='pending')
ip_address = Column(String)
request_time = Column(DateTime, default=datetime.utcnow, index=True)
request_last_updated_time = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
user_input = Column(JSON)
input_data_string = Column(Text)
api_request = Column(JSON)
api_response = Column(JSON)
api_session_id = Column(String, nullable=True, unique=True)
total_cost = Column(Numeric(10, 10), nullable=True)
customer_email = Column(String, ForeignKey('customer.email'))
customer = relationship("Customer", back_populates="service_requests")
# AuditLog
class GenericAuditLog(Base):
__tablename__ = 'generic_audit_log'
id = Column(Integer, primary_key=True, index=True)
action_type = Column(String, nullable=False, index=True)
outcome = Column(String, nullable=True)
field_affected = Column(String, nullable=True)
prev_value = Column(JSON, nullable=True)
new_value = Column(JSON, nullable=True)
actor_email = Column(String, ForeignKey('generic_user.email'), index=True)
related_request_id = Column(Integer, ForeignKey('generic_user_request.unique_id'))
timestamp = Column(DateTime, default=datetime.utcnow)
actor = relationship("GenericUser", back_populates="audit_logs")
# Feedback
class GenericFeedback(Base):
__tablename__ = 'generic_feedback'
id = Column(Integer, primary_key=True, index=True)
score = Column(Integer, nullable=False)
commentary = Column(Text, nullable=True)
customer_email = Column(String, ForeignKey('customer.email'), index=True)
content_creator_email = Column(String, ForeignKey('content_creator.email'), index=True)
request_id = Column(Integer, ForeignKey('generic_user_request.unique_id'))
last_updated = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
is_removed = Column(Boolean, default=False)
removed_at = Column(DateTime, nullable=True)
customer = relationship("Customer", back_populates="feedbacks_provided")
content_creator = relationship("ContentCreator", back_populates="feedbacks_received")
# APIKeys
class GenericAPIKey(Base):
__tablename__ = 'generic_api_key'
id = Column(Integer, primary_key=True, index=True)
api_key = Column(String, unique=True, nullable=False)
content_creator_email = Column(String, ForeignKey('content_creator.email'), index=True)
is_active = Column(Boolean, default=True)
is_revoked = Column(Boolean, default=False)
expires_at = Column(DateTime, nullable=True)
created_at = Column(DateTime, default=datetime.utcnow)
content_creator = relationship("ContentCreator", back_populates="api_keys")
# Notification
class GenericNotification(Base):
__tablename__ = 'generic_notification'
id = Column(Integer, primary_key=True, index=True)
recipient_email = Column(String, ForeignKey('generic_user.email'), index=True)
notification_kind = Column(String, nullable=False)
is_read = Column(Boolean, default=False)
content = Column(Text, nullable=False)
created_at = Column(DateTime, default=datetime.utcnow)
read_at = Column(DateTime, nullable=True)
recipient = relationship("GenericUser", back_populates="notifications")
# APICreditLog
class GenericAPICreditLog(Base):
__tablename__ = 'generic_api_credit_log'
id = Column(Integer, primary_key=True, index=True)
timestamp = Column(DateTime, default=datetime.utcnow)
is_paid = Column(Boolean, default=False)
status = Column(String, default='pending')
expense = Column(Numeric(10, 10), nullable=False)
request_id = Column(Integer, ForeignKey('generic_user_request.unique_id'))
token_count = Column(Integer, nullable=False)
content_creator_email = Column(String, ForeignKey('content_creator.email'))
content_creator = relationship("ContentCreator", back_populates="api_credit_logs")
# SubscriptionType
class GenericSubscriptionType(Base):
__tablename__ = 'generic_subscription_type'
id = Column(Integer, primary_key=True, index=True)
name = Column(String, nullable=False)
monthly_fee = Column(Numeric(10, 10), nullable=False)
monthly_cap = Column(Integer, nullable=False)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
is_removed = Column(Boolean, default=False)
removed_at = Column(DateTime, nullable=True)
subscriptions = relationship("GenericSubscription", back_populates="subscription_type")
# Subscription
class GenericSubscription(Base):
__tablename__ = 'generic_subscription'
id = Column(Integer, primary_key=True, index=True)
customer_email = Column(String, ForeignKey('customer.email'), index=True)
start_date = Column(DateTime, default=datetime.utcnow)
end_date = Column(DateTime, nullable=True)
current_use = Column(Integer, default=0)
subscription_type_id = Column(Integer, ForeignKey('generic_subscription_type.id'))
customer = relationship("Customer", back_populates="subscriptions")
subscription_type = relationship("GenericSubscriptionType", back_populates="subscriptions")
subscription_usages = relationship("GenericSubscriptionUsage", back_populates="subscription")
# SubscriptionUsage
class GenericSubscriptionUsage(Base):
__tablename__ = 'generic_subscription_usage'
id = Column(Integer, primary_key=True, index=True)
customer_email = Column(String, ForeignKey('customer.email'), index=True)
use_count = Column(Integer, default=0)
last_use = Column(DateTime, nullable=True)
subscription_id = Column(Integer, ForeignKey('generic_subscription.id'))
subscription_type_id = Column(Integer, ForeignKey('generic_subscription_type.id'))
customer = relationship("Customer", back_populates="subscription_usages")
subscription = relationship("GenericSubscription", back_populates="subscription_usages")
subscription_type = relationship("GenericSubscriptionType", backref="subscription_usages")
# BillingInfo
class GenericBillingInfo(Base):
__tablename__ = 'generic_billing_info'
id = Column(Integer, primary_key=True, index=True)
customer_email = Column(String, ForeignKey('customer.email'), index=True)
payment_type = Column(String, nullable=False)
payment_data = Column(JSON)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
is_removed = Column(Boolean, default=False)
removed_at = Column(DateTime, nullable=True)
customer = relationship("Customer", back_populates="billing_infos")
models = [GenericUser, Customer, ContentCreator, UserSession, FileStorage, ServiceRequest, GenericAuditLog, GenericFeedback, GenericAPIKey, GenericNotification, GenericAPICreditLog, GenericSubscriptionType, GenericSubscription, GenericSubscriptionUsage, GenericBillingInfo]
output_file_name = 'my_data_model_diagram'
# Generate the diagram and add interactivity
generate_data_model_diagram(models, output_file_name, add_labels=True)
add_web_font_and_interactivity('my_data_model_diagram.svg', 'my_interactive_data_model_diagram.svg')
gitextract_lqxycubh/ ├── .github/ │ └── workflows/ │ └── python-publish.yml ├── .gitignore ├── LICENSE ├── MANIFEST.in ├── README.md ├── requirements.txt ├── setup.py └── sqlalchemy_data_model_visualizer.py
SYMBOL INDEX (17 symbols across 1 files) FILE: sqlalchemy_data_model_visualizer.py function generate_data_model_diagram (line 15) | def generate_data_model_diagram(models, output_file='my_data_model_diagr... function add_web_font_and_interactivity (line 65) | def add_web_font_and_interactivity(input_svg_file, output_svg_file): class GenericUser (line 103) | class GenericUser(Base): class Customer (line 123) | class Customer(Base): class ContentCreator (line 134) | class ContentCreator(Base): class UserSession (line 146) | class UserSession(Base): class FileStorage (line 157) | class FileStorage(Base): class ServiceRequest (line 165) | class ServiceRequest(Base): class GenericAuditLog (line 182) | class GenericAuditLog(Base): class GenericFeedback (line 196) | class GenericFeedback(Base): class GenericAPIKey (line 211) | class GenericAPIKey(Base): class GenericNotification (line 223) | class GenericNotification(Base): class GenericAPICreditLog (line 235) | class GenericAPICreditLog(Base): class GenericSubscriptionType (line 248) | class GenericSubscriptionType(Base): class GenericSubscription (line 261) | class GenericSubscription(Base): class GenericSubscriptionUsage (line 274) | class GenericSubscriptionUsage(Base): class GenericBillingInfo (line 287) | class GenericBillingInfo(Base):
Condensed preview — 8 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (28K chars).
[
{
"path": ".github/workflows/python-publish.yml",
"chars": 743,
"preview": "name: Build and Publish to PyPI\n\non:\n push:\n branches:\n - main \n release:\n types: [created]\n\njobs:\n build"
},
{
"path": ".gitignore",
"chars": 3078,
"preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packagi"
},
{
"path": "LICENSE",
"chars": 1069,
"preview": "MIT License\n\nCopyright (c) 2023 Jeff Emanuel\n\nPermission is hereby granted, free of charge, to any person obtaining a co"
},
{
"path": "MANIFEST.in",
"chars": 25,
"preview": "include requirements.txt\n"
},
{
"path": "README.md",
"chars": 5146,
"preview": "# SQLAlchemy Data Model Visualizer\n\n## Overview\n\nThis Python-based utility generates high-quality, readable visualizatio"
},
{
"path": "requirements.txt",
"chars": 25,
"preview": "sqlalchemy\ngraphviz\nlxml\n"
},
{
"path": "setup.py",
"chars": 1485,
"preview": "from setuptools import setup\nfrom pathlib import Path\n\n# Define the directory where this setup.py file is located\nhere ="
},
{
"path": "sqlalchemy_data_model_visualizer.py",
"chars": 15651,
"preview": "from datetime import datetime\nfrom typing import Optional\nfrom enum import Enum\nfrom decimal import Decimal\nfrom sqlalch"
}
]
About this extraction
This page contains the full source code of the Dicklesworthstone/sqlalchemy_data_model_visualizer GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 8 files (26.6 KB), approximately 6.1k tokens, and a symbol index with 17 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.