📝 Add code example for sa_columnonupdate timestamps - #372

Closed
RobertRosca wants to merge 7 commits into
fastapi:mainfrom
RobertRosca:docs/created_updated_at_cols
Closed

📝 Add code example for sa_columnonupdate timestamps#372
RobertRosca wants to merge 7 commits into
fastapi:mainfrom
RobertRosca:docs/created_updated_at_cols

Conversation

@RobertRosca

Copy link
Copy Markdown
Contributor

Issue #370 is a common usecase and there have been a few other questions about how to implement created_at or updated_at timestamps in rows. This PR adds examples to the advanced section of the documentation on how this can be done with sa_columns, and also links the relevant sections of Pydantic documentation which show how to use factories or validators to achieve a similar thing with Pydantic.

@RobertRosca
RobertRoscaforce-pushed the docs/created_updated_at_cols branch from d53330d to 893bcf3CompareSeptember 3, 2022 09:12
@codecov

This comment was marked as outdated.

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit 893bcf3 at: https://63131ab0d8aeff704c33fd2d--sqlmodel.netlify.app

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit 1e5caaa at: https://6326cad9fcbd027752da81e2--sqlmodel.netlify.app

Comment threaddocs/advanced/sa-column.md Outdated
Comment threaddocs/advanced/sa-column.md
@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit d78fc71 at: https://636244bbeb67cb7064300959--sqlmodel.netlify.app

@RobertRosca

Copy link
Copy Markdown
ContributorAuthor

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit b160fc8 at: https://639ce08a1f184e006c3a2967--sqlmodel.netlify.app

@tiangolotiangolo added the docs Improvements or additions to documentation label Oct 22, 2023
@MRigal

Copy link
Copy Markdown

This is actually very valuable documentation which I was a bit missing. What is it missing to get merged?

@github-actions

This comment was marked as outdated.

@YuriiMotovYuriiMotov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RobertRosca, thanks for working on this!

I think it would be better to start from describing the Pydantic implementation (only default_factory, no need to focus on this that much), then highlight its weak points and then present the solution with server_default and onupdate.

Also, code example should be covered by test.
Later we could also add an alternative way to implement this using sa_type and sa_column_kwargs.

See also my other in-code comments.

Are you ready to continue working on this?

Comment on lines +57 to +70
Another approach is to use a Pydantic `validator`:

```python
from datetime import datetime

from pydantic import BaseModel, validator

class Model(BaseModel):
created_at: datetime = None

@validator('ts', pre=True, always=True)
def set_created_at_now(cls, v):
return v or datetime.now()
```

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove this code example with validator

Comment threaddocs/advanced/sa-column.md Outdated
age: Optional[int] = None

registered_at: datetime = Field(
sa_column=Column(DateTime(timezone=False), server_default=func.now())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add nullable=False?

)

updated_at: Optional[datetime] = Field(
sa_column=Column(DateTime(timezone=False), onupdate=func.now())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add server_default=func.now() and nullable=False?

Comment on lines +36 to +37
hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only update hero1, I would remove hero2 and hero3 to simplify the example

session.close()


def update_hero_age(new_secret_name):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defupdate_hero_age(new_secret_name):
defupdate_hero_secret_name(new_secret_name):

def main():
create_db_and_tables()
create_heroes()
sleep(1)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to find way to avoid sleeping as it will make test run slower

Comment threaddocs/advanced/sa-column.md Outdated
Comment threaddocs/advanced/sa-column.md Outdated
@YuriiMotovYuriiMotov changed the title 📝 Add example code for sa_column onupdate timestamps📝 Add code example for sa_columnonupdate timestampsAug 25, 2025
@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

As this PR has been waiting for the original user for a while but seems to be inactive, it's now going to be closed. But if there's anyone interested, feel free to create a new PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docsImprovements or additions to documentationinvestigatewaiting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@RobertRosca@MRigal@paolodina@YuriiMotov@tiangolo
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

📝 Add code example for sa_columnonupdate timestamps - #372

Closed
RobertRosca wants to merge 7 commits into
fastapi:mainfrom
RobertRosca:docs/created_updated_at_cols
Closed

📝 Add code example for sa_columnonupdate timestamps#372
RobertRosca wants to merge 7 commits into
fastapi:mainfrom
RobertRosca:docs/created_updated_at_cols

Conversation

@RobertRosca

Copy link
Copy Markdown
Contributor

Issue #370 is a common usecase and there have been a few other questions about how to implement created_at or updated_at timestamps in rows. This PR adds examples to the advanced section of the documentation on how this can be done with sa_columns, and also links the relevant sections of Pydantic documentation which show how to use factories or validators to achieve a similar thing with Pydantic.

@RobertRosca
RobertRoscaforce-pushed the docs/created_updated_at_cols branch from d53330d to 893bcf3CompareSeptember 3, 2022 09:12
@codecov

This comment was marked as outdated.

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit 893bcf3 at: https://63131ab0d8aeff704c33fd2d--sqlmodel.netlify.app

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit 1e5caaa at: https://6326cad9fcbd027752da81e2--sqlmodel.netlify.app

Comment threaddocs/advanced/sa-column.md Outdated
Comment threaddocs/advanced/sa-column.md
@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit d78fc71 at: https://636244bbeb67cb7064300959--sqlmodel.netlify.app

@RobertRosca

Copy link
Copy Markdown
ContributorAuthor

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit b160fc8 at: https://639ce08a1f184e006c3a2967--sqlmodel.netlify.app

@tiangolotiangolo added the docs Improvements or additions to documentation label Oct 22, 2023
@MRigal

Copy link
Copy Markdown

This is actually very valuable documentation which I was a bit missing. What is it missing to get merged?

@github-actions

This comment was marked as outdated.

@YuriiMotovYuriiMotov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RobertRosca, thanks for working on this!

I think it would be better to start from describing the Pydantic implementation (only default_factory, no need to focus on this that much), then highlight its weak points and then present the solution with server_default and onupdate.

Also, code example should be covered by test.
Later we could also add an alternative way to implement this using sa_type and sa_column_kwargs.

See also my other in-code comments.

Are you ready to continue working on this?

Comment on lines +57 to +70
Another approach is to use a Pydantic `validator`:

```python
from datetime import datetime

from pydantic import BaseModel, validator

class Model(BaseModel):
created_at: datetime = None

@validator('ts', pre=True, always=True)
def set_created_at_now(cls, v):
return v or datetime.now()
```

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove this code example with validator

Comment threaddocs/advanced/sa-column.md Outdated
age: Optional[int] = None

registered_at: datetime = Field(
sa_column=Column(DateTime(timezone=False), server_default=func.now())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add nullable=False?

)

updated_at: Optional[datetime] = Field(
sa_column=Column(DateTime(timezone=False), onupdate=func.now())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add server_default=func.now() and nullable=False?

Comment on lines +36 to +37
hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only update hero1, I would remove hero2 and hero3 to simplify the example

session.close()


def update_hero_age(new_secret_name):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defupdate_hero_age(new_secret_name):
defupdate_hero_secret_name(new_secret_name):

def main():
create_db_and_tables()
create_heroes()
sleep(1)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to find way to avoid sleeping as it will make test run slower

Comment threaddocs/advanced/sa-column.md Outdated
Comment threaddocs/advanced/sa-column.md Outdated
@YuriiMotovYuriiMotov changed the title 📝 Add example code for sa_column onupdate timestamps📝 Add code example for sa_columnonupdate timestampsAug 25, 2025
@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

As this PR has been waiting for the original user for a while but seems to be inactive, it's now going to be closed. But if there's anyone interested, feel free to create a new PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docsImprovements or additions to documentationinvestigatewaiting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@RobertRosca@MRigal@paolodina@YuriiMotov@tiangolo
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

📝 Add code example for sa_columnonupdate timestamps - #372

Closed
RobertRosca wants to merge 7 commits into
fastapi:mainfrom
RobertRosca:docs/created_updated_at_cols
Closed

📝 Add code example for sa_columnonupdate timestamps#372
RobertRosca wants to merge 7 commits into
fastapi:mainfrom
RobertRosca:docs/created_updated_at_cols

Conversation

@RobertRosca

Copy link
Copy Markdown
Contributor

Issue #370 is a common usecase and there have been a few other questions about how to implement created_at or updated_at timestamps in rows. This PR adds examples to the advanced section of the documentation on how this can be done with sa_columns, and also links the relevant sections of Pydantic documentation which show how to use factories or validators to achieve a similar thing with Pydantic.

@RobertRosca
RobertRoscaforce-pushed the docs/created_updated_at_cols branch from d53330d to 893bcf3CompareSeptember 3, 2022 09:12
@codecov

This comment was marked as outdated.

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit 893bcf3 at: https://63131ab0d8aeff704c33fd2d--sqlmodel.netlify.app

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit 1e5caaa at: https://6326cad9fcbd027752da81e2--sqlmodel.netlify.app

Comment threaddocs/advanced/sa-column.md Outdated
Comment threaddocs/advanced/sa-column.md
@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit d78fc71 at: https://636244bbeb67cb7064300959--sqlmodel.netlify.app

@RobertRosca

Copy link
Copy Markdown
ContributorAuthor

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit b160fc8 at: https://639ce08a1f184e006c3a2967--sqlmodel.netlify.app

@tiangolotiangolo added the docs Improvements or additions to documentation label Oct 22, 2023
@MRigal

Copy link
Copy Markdown

This is actually very valuable documentation which I was a bit missing. What is it missing to get merged?

@github-actions

This comment was marked as outdated.

@YuriiMotovYuriiMotov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RobertRosca, thanks for working on this!

I think it would be better to start from describing the Pydantic implementation (only default_factory, no need to focus on this that much), then highlight its weak points and then present the solution with server_default and onupdate.

Also, code example should be covered by test.
Later we could also add an alternative way to implement this using sa_type and sa_column_kwargs.

See also my other in-code comments.

Are you ready to continue working on this?

Comment on lines +57 to +70
Another approach is to use a Pydantic `validator`:

```python
from datetime import datetime

from pydantic import BaseModel, validator

class Model(BaseModel):
created_at: datetime = None

@validator('ts', pre=True, always=True)
def set_created_at_now(cls, v):
return v or datetime.now()
```

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove this code example with validator

Comment threaddocs/advanced/sa-column.md Outdated
age: Optional[int] = None

registered_at: datetime = Field(
sa_column=Column(DateTime(timezone=False), server_default=func.now())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add nullable=False?

)

updated_at: Optional[datetime] = Field(
sa_column=Column(DateTime(timezone=False), onupdate=func.now())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add server_default=func.now() and nullable=False?

Comment on lines +36 to +37
hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only update hero1, I would remove hero2 and hero3 to simplify the example

session.close()


def update_hero_age(new_secret_name):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defupdate_hero_age(new_secret_name):
defupdate_hero_secret_name(new_secret_name):

def main():
create_db_and_tables()
create_heroes()
sleep(1)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to find way to avoid sleeping as it will make test run slower

Comment threaddocs/advanced/sa-column.md Outdated
Comment threaddocs/advanced/sa-column.md Outdated
@YuriiMotovYuriiMotov changed the title 📝 Add example code for sa_column onupdate timestamps📝 Add code example for sa_columnonupdate timestampsAug 25, 2025
@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

As this PR has been waiting for the original user for a while but seems to be inactive, it's now going to be closed. But if there's anyone interested, feel free to create a new PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docsImprovements or additions to documentationinvestigatewaiting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@RobertRosca@MRigal@paolodina@YuriiMotov@tiangolo
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

📝 Add code example for sa_columnonupdate timestamps - #372

Closed
RobertRosca wants to merge 7 commits into
fastapi:mainfrom
RobertRosca:docs/created_updated_at_cols
Closed

📝 Add code example for sa_columnonupdate timestamps#372
RobertRosca wants to merge 7 commits into
fastapi:mainfrom
RobertRosca:docs/created_updated_at_cols

Conversation

@RobertRosca

Copy link
Copy Markdown
Contributor

Issue #370 is a common usecase and there have been a few other questions about how to implement created_at or updated_at timestamps in rows. This PR adds examples to the advanced section of the documentation on how this can be done with sa_columns, and also links the relevant sections of Pydantic documentation which show how to use factories or validators to achieve a similar thing with Pydantic.

@RobertRosca
RobertRoscaforce-pushed the docs/created_updated_at_cols branch from d53330d to 893bcf3CompareSeptember 3, 2022 09:12
@codecov

This comment was marked as outdated.

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit 893bcf3 at: https://63131ab0d8aeff704c33fd2d--sqlmodel.netlify.app

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit 1e5caaa at: https://6326cad9fcbd027752da81e2--sqlmodel.netlify.app

Comment threaddocs/advanced/sa-column.md Outdated
Comment threaddocs/advanced/sa-column.md
@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit d78fc71 at: https://636244bbeb67cb7064300959--sqlmodel.netlify.app

@RobertRosca

Copy link
Copy Markdown
ContributorAuthor

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit b160fc8 at: https://639ce08a1f184e006c3a2967--sqlmodel.netlify.app

@tiangolotiangolo added the docs Improvements or additions to documentation label Oct 22, 2023
@MRigal

Copy link
Copy Markdown

This is actually very valuable documentation which I was a bit missing. What is it missing to get merged?

@github-actions

This comment was marked as outdated.

@YuriiMotovYuriiMotov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RobertRosca, thanks for working on this!

I think it would be better to start from describing the Pydantic implementation (only default_factory, no need to focus on this that much), then highlight its weak points and then present the solution with server_default and onupdate.

Also, code example should be covered by test.
Later we could also add an alternative way to implement this using sa_type and sa_column_kwargs.

See also my other in-code comments.

Are you ready to continue working on this?

Comment on lines +57 to +70
Another approach is to use a Pydantic `validator`:

```python
from datetime import datetime

from pydantic import BaseModel, validator

class Model(BaseModel):
created_at: datetime = None

@validator('ts', pre=True, always=True)
def set_created_at_now(cls, v):
return v or datetime.now()
```

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove this code example with validator

Comment threaddocs/advanced/sa-column.md Outdated
age: Optional[int] = None

registered_at: datetime = Field(
sa_column=Column(DateTime(timezone=False), server_default=func.now())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add nullable=False?

)

updated_at: Optional[datetime] = Field(
sa_column=Column(DateTime(timezone=False), onupdate=func.now())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add server_default=func.now() and nullable=False?

Comment on lines +36 to +37
hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only update hero1, I would remove hero2 and hero3 to simplify the example

session.close()


def update_hero_age(new_secret_name):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defupdate_hero_age(new_secret_name):
defupdate_hero_secret_name(new_secret_name):

def main():
create_db_and_tables()
create_heroes()
sleep(1)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to find way to avoid sleeping as it will make test run slower

Comment threaddocs/advanced/sa-column.md Outdated
Comment threaddocs/advanced/sa-column.md Outdated
@YuriiMotovYuriiMotov changed the title 📝 Add example code for sa_column onupdate timestamps📝 Add code example for sa_columnonupdate timestampsAug 25, 2025
@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

As this PR has been waiting for the original user for a while but seems to be inactive, it's now going to be closed. But if there's anyone interested, feel free to create a new PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docsImprovements or additions to documentationinvestigatewaiting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@RobertRosca@MRigal@paolodina@YuriiMotov@tiangolo
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

📝 Add code example for sa_columnonupdate timestamps - #372

Closed
RobertRosca wants to merge 7 commits into
fastapi:mainfrom
RobertRosca:docs/created_updated_at_cols
Closed

📝 Add code example for sa_columnonupdate timestamps#372
RobertRosca wants to merge 7 commits into
fastapi:mainfrom
RobertRosca:docs/created_updated_at_cols

Conversation

@RobertRosca

Copy link
Copy Markdown
Contributor

Issue #370 is a common usecase and there have been a few other questions about how to implement created_at or updated_at timestamps in rows. This PR adds examples to the advanced section of the documentation on how this can be done with sa_columns, and also links the relevant sections of Pydantic documentation which show how to use factories or validators to achieve a similar thing with Pydantic.

@RobertRosca
RobertRoscaforce-pushed the docs/created_updated_at_cols branch from d53330d to 893bcf3CompareSeptember 3, 2022 09:12
@codecov

This comment was marked as outdated.

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit 893bcf3 at: https://63131ab0d8aeff704c33fd2d--sqlmodel.netlify.app

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit 1e5caaa at: https://6326cad9fcbd027752da81e2--sqlmodel.netlify.app

Comment threaddocs/advanced/sa-column.md Outdated
Comment threaddocs/advanced/sa-column.md
@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit d78fc71 at: https://636244bbeb67cb7064300959--sqlmodel.netlify.app

@RobertRosca

Copy link
Copy Markdown
ContributorAuthor

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit b160fc8 at: https://639ce08a1f184e006c3a2967--sqlmodel.netlify.app

@tiangolotiangolo added the docs Improvements or additions to documentation label Oct 22, 2023
@MRigal

Copy link
Copy Markdown

This is actually very valuable documentation which I was a bit missing. What is it missing to get merged?

@github-actions

This comment was marked as outdated.

@YuriiMotovYuriiMotov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RobertRosca, thanks for working on this!

I think it would be better to start from describing the Pydantic implementation (only default_factory, no need to focus on this that much), then highlight its weak points and then present the solution with server_default and onupdate.

Also, code example should be covered by test.
Later we could also add an alternative way to implement this using sa_type and sa_column_kwargs.

See also my other in-code comments.

Are you ready to continue working on this?

Comment on lines +57 to +70
Another approach is to use a Pydantic `validator`:

```python
from datetime import datetime

from pydantic import BaseModel, validator

class Model(BaseModel):
created_at: datetime = None

@validator('ts', pre=True, always=True)
def set_created_at_now(cls, v):
return v or datetime.now()
```

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove this code example with validator

Comment threaddocs/advanced/sa-column.md Outdated
age: Optional[int] = None

registered_at: datetime = Field(
sa_column=Column(DateTime(timezone=False), server_default=func.now())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add nullable=False?

)

updated_at: Optional[datetime] = Field(
sa_column=Column(DateTime(timezone=False), onupdate=func.now())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add server_default=func.now() and nullable=False?

Comment on lines +36 to +37
hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only update hero1, I would remove hero2 and hero3 to simplify the example

session.close()


def update_hero_age(new_secret_name):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defupdate_hero_age(new_secret_name):
defupdate_hero_secret_name(new_secret_name):

def main():
create_db_and_tables()
create_heroes()
sleep(1)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to find way to avoid sleeping as it will make test run slower

Comment threaddocs/advanced/sa-column.md Outdated
Comment threaddocs/advanced/sa-column.md Outdated
@YuriiMotovYuriiMotov changed the title 📝 Add example code for sa_column onupdate timestamps📝 Add code example for sa_columnonupdate timestampsAug 25, 2025
@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

As this PR has been waiting for the original user for a while but seems to be inactive, it's now going to be closed. But if there's anyone interested, feel free to create a new PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docsImprovements or additions to documentationinvestigatewaiting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@RobertRosca@MRigal@paolodina@YuriiMotov@tiangolo
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

📝 Add code example for sa_columnonupdate timestamps - #372

Closed
RobertRosca wants to merge 7 commits into
fastapi:mainfrom
RobertRosca:docs/created_updated_at_cols
Closed

📝 Add code example for sa_columnonupdate timestamps#372
RobertRosca wants to merge 7 commits into
fastapi:mainfrom
RobertRosca:docs/created_updated_at_cols

Conversation

@RobertRosca

Copy link
Copy Markdown
Contributor

Issue #370 is a common usecase and there have been a few other questions about how to implement created_at or updated_at timestamps in rows. This PR adds examples to the advanced section of the documentation on how this can be done with sa_columns, and also links the relevant sections of Pydantic documentation which show how to use factories or validators to achieve a similar thing with Pydantic.

@RobertRosca
RobertRoscaforce-pushed the docs/created_updated_at_cols branch from d53330d to 893bcf3CompareSeptember 3, 2022 09:12
@codecov

This comment was marked as outdated.

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit 893bcf3 at: https://63131ab0d8aeff704c33fd2d--sqlmodel.netlify.app

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit 1e5caaa at: https://6326cad9fcbd027752da81e2--sqlmodel.netlify.app

Comment threaddocs/advanced/sa-column.md Outdated
Comment threaddocs/advanced/sa-column.md
@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit d78fc71 at: https://636244bbeb67cb7064300959--sqlmodel.netlify.app

@RobertRosca

Copy link
Copy Markdown
ContributorAuthor

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit b160fc8 at: https://639ce08a1f184e006c3a2967--sqlmodel.netlify.app

@tiangolotiangolo added the docs Improvements or additions to documentation label Oct 22, 2023
@MRigal

Copy link
Copy Markdown

This is actually very valuable documentation which I was a bit missing. What is it missing to get merged?

@github-actions

This comment was marked as outdated.

@YuriiMotovYuriiMotov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RobertRosca, thanks for working on this!

I think it would be better to start from describing the Pydantic implementation (only default_factory, no need to focus on this that much), then highlight its weak points and then present the solution with server_default and onupdate.

Also, code example should be covered by test.
Later we could also add an alternative way to implement this using sa_type and sa_column_kwargs.

See also my other in-code comments.

Are you ready to continue working on this?

Comment on lines +57 to +70
Another approach is to use a Pydantic `validator`:

```python
from datetime import datetime

from pydantic import BaseModel, validator

class Model(BaseModel):
created_at: datetime = None

@validator('ts', pre=True, always=True)
def set_created_at_now(cls, v):
return v or datetime.now()
```

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove this code example with validator

Comment threaddocs/advanced/sa-column.md Outdated
age: Optional[int] = None

registered_at: datetime = Field(
sa_column=Column(DateTime(timezone=False), server_default=func.now())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add nullable=False?

)

updated_at: Optional[datetime] = Field(
sa_column=Column(DateTime(timezone=False), onupdate=func.now())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add server_default=func.now() and nullable=False?

Comment on lines +36 to +37
hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only update hero1, I would remove hero2 and hero3 to simplify the example

session.close()


def update_hero_age(new_secret_name):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defupdate_hero_age(new_secret_name):
defupdate_hero_secret_name(new_secret_name):

def main():
create_db_and_tables()
create_heroes()
sleep(1)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to find way to avoid sleeping as it will make test run slower

Comment threaddocs/advanced/sa-column.md Outdated
Comment threaddocs/advanced/sa-column.md Outdated
@YuriiMotovYuriiMotov changed the title 📝 Add example code for sa_column onupdate timestamps📝 Add code example for sa_columnonupdate timestampsAug 25, 2025
@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

As this PR has been waiting for the original user for a while but seems to be inactive, it's now going to be closed. But if there's anyone interested, feel free to create a new PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docsImprovements or additions to documentationinvestigatewaiting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@RobertRosca@MRigal@paolodina@YuriiMotov@tiangolo
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

📝 Add code example for sa_columnonupdate timestamps - #372

Closed
RobertRosca wants to merge 7 commits into
fastapi:mainfrom
RobertRosca:docs/created_updated_at_cols
Closed

📝 Add code example for sa_columnonupdate timestamps#372
RobertRosca wants to merge 7 commits into
fastapi:mainfrom
RobertRosca:docs/created_updated_at_cols

Conversation

@RobertRosca

Copy link
Copy Markdown
Contributor

Issue #370 is a common usecase and there have been a few other questions about how to implement created_at or updated_at timestamps in rows. This PR adds examples to the advanced section of the documentation on how this can be done with sa_columns, and also links the relevant sections of Pydantic documentation which show how to use factories or validators to achieve a similar thing with Pydantic.

@RobertRosca
RobertRoscaforce-pushed the docs/created_updated_at_cols branch from d53330d to 893bcf3CompareSeptember 3, 2022 09:12
@codecov

This comment was marked as outdated.

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit 893bcf3 at: https://63131ab0d8aeff704c33fd2d--sqlmodel.netlify.app

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit 1e5caaa at: https://6326cad9fcbd027752da81e2--sqlmodel.netlify.app

Comment threaddocs/advanced/sa-column.md Outdated
Comment threaddocs/advanced/sa-column.md
@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit d78fc71 at: https://636244bbeb67cb7064300959--sqlmodel.netlify.app

@RobertRosca

Copy link
Copy Markdown
ContributorAuthor

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit b160fc8 at: https://639ce08a1f184e006c3a2967--sqlmodel.netlify.app

@tiangolotiangolo added the docs Improvements or additions to documentation label Oct 22, 2023
@MRigal

Copy link
Copy Markdown

This is actually very valuable documentation which I was a bit missing. What is it missing to get merged?

@github-actions

This comment was marked as outdated.

@YuriiMotovYuriiMotov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RobertRosca, thanks for working on this!

I think it would be better to start from describing the Pydantic implementation (only default_factory, no need to focus on this that much), then highlight its weak points and then present the solution with server_default and onupdate.

Also, code example should be covered by test.
Later we could also add an alternative way to implement this using sa_type and sa_column_kwargs.

See also my other in-code comments.

Are you ready to continue working on this?

Comment on lines +57 to +70
Another approach is to use a Pydantic `validator`:

```python
from datetime import datetime

from pydantic import BaseModel, validator

class Model(BaseModel):
created_at: datetime = None

@validator('ts', pre=True, always=True)
def set_created_at_now(cls, v):
return v or datetime.now()
```

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove this code example with validator

Comment threaddocs/advanced/sa-column.md Outdated
age: Optional[int] = None

registered_at: datetime = Field(
sa_column=Column(DateTime(timezone=False), server_default=func.now())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add nullable=False?

)

updated_at: Optional[datetime] = Field(
sa_column=Column(DateTime(timezone=False), onupdate=func.now())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add server_default=func.now() and nullable=False?

Comment on lines +36 to +37
hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only update hero1, I would remove hero2 and hero3 to simplify the example

session.close()


def update_hero_age(new_secret_name):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defupdate_hero_age(new_secret_name):
defupdate_hero_secret_name(new_secret_name):

def main():
create_db_and_tables()
create_heroes()
sleep(1)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to find way to avoid sleeping as it will make test run slower

Comment threaddocs/advanced/sa-column.md Outdated
Comment threaddocs/advanced/sa-column.md Outdated
@YuriiMotovYuriiMotov changed the title 📝 Add example code for sa_column onupdate timestamps📝 Add code example for sa_columnonupdate timestampsAug 25, 2025
@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

As this PR has been waiting for the original user for a while but seems to be inactive, it's now going to be closed. But if there's anyone interested, feel free to create a new PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docsImprovements or additions to documentationinvestigatewaiting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@RobertRosca@MRigal@paolodina@YuriiMotov@tiangolo
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

📝 Add code example for sa_columnonupdate timestamps - #372

Closed
RobertRosca wants to merge 7 commits into
fastapi:mainfrom
RobertRosca:docs/created_updated_at_cols
Closed

📝 Add code example for sa_columnonupdate timestamps#372
RobertRosca wants to merge 7 commits into
fastapi:mainfrom
RobertRosca:docs/created_updated_at_cols

Conversation

@RobertRosca

Copy link
Copy Markdown
Contributor

Issue #370 is a common usecase and there have been a few other questions about how to implement created_at or updated_at timestamps in rows. This PR adds examples to the advanced section of the documentation on how this can be done with sa_columns, and also links the relevant sections of Pydantic documentation which show how to use factories or validators to achieve a similar thing with Pydantic.

@RobertRosca
RobertRoscaforce-pushed the docs/created_updated_at_cols branch from d53330d to 893bcf3CompareSeptember 3, 2022 09:12
@codecov

This comment was marked as outdated.

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit 893bcf3 at: https://63131ab0d8aeff704c33fd2d--sqlmodel.netlify.app

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit 1e5caaa at: https://6326cad9fcbd027752da81e2--sqlmodel.netlify.app

Comment threaddocs/advanced/sa-column.md Outdated
Comment threaddocs/advanced/sa-column.md
@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit d78fc71 at: https://636244bbeb67cb7064300959--sqlmodel.netlify.app

@RobertRosca

Copy link
Copy Markdown
ContributorAuthor

@github-actions

Copy link
Copy Markdown
Contributor

📝 Docs preview for commit b160fc8 at: https://639ce08a1f184e006c3a2967--sqlmodel.netlify.app

@tiangolotiangolo added the docs Improvements or additions to documentation label Oct 22, 2023
@MRigal

Copy link
Copy Markdown

This is actually very valuable documentation which I was a bit missing. What is it missing to get merged?

@github-actions

This comment was marked as outdated.

@YuriiMotovYuriiMotov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RobertRosca, thanks for working on this!

I think it would be better to start from describing the Pydantic implementation (only default_factory, no need to focus on this that much), then highlight its weak points and then present the solution with server_default and onupdate.

Also, code example should be covered by test.
Later we could also add an alternative way to implement this using sa_type and sa_column_kwargs.

See also my other in-code comments.

Are you ready to continue working on this?

Comment on lines +57 to +70
Another approach is to use a Pydantic `validator`:

```python
from datetime import datetime

from pydantic import BaseModel, validator

class Model(BaseModel):
created_at: datetime = None

@validator('ts', pre=True, always=True)
def set_created_at_now(cls, v):
return v or datetime.now()
```

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove this code example with validator

Comment threaddocs/advanced/sa-column.md Outdated
age: Optional[int] = None

registered_at: datetime = Field(
sa_column=Column(DateTime(timezone=False), server_default=func.now())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add nullable=False?

)

updated_at: Optional[datetime] = Field(
sa_column=Column(DateTime(timezone=False), onupdate=func.now())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add server_default=func.now() and nullable=False?

Comment on lines +36 to +37
hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only update hero1, I would remove hero2 and hero3 to simplify the example

session.close()


def update_hero_age(new_secret_name):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defupdate_hero_age(new_secret_name):
defupdate_hero_secret_name(new_secret_name):

def main():
create_db_and_tables()
create_heroes()
sleep(1)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to find way to avoid sleeping as it will make test run slower

Comment threaddocs/advanced/sa-column.md Outdated
Comment threaddocs/advanced/sa-column.md Outdated
@YuriiMotovYuriiMotov changed the title 📝 Add example code for sa_column onupdate timestamps📝 Add code example for sa_columnonupdate timestampsAug 25, 2025
@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

As this PR has been waiting for the original user for a while but seems to be inactive, it's now going to be closed. But if there's anyone interested, feel free to create a new PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docsImprovements or additions to documentationinvestigatewaiting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@RobertRosca@MRigal@paolodina@YuriiMotov@tiangolo