|
25 | 25 |
|
26 | 26 | from pydantic import BaseConfig, BaseModel |
27 | 27 | from pydantic.errors import ConfigError, DictError |
| 28 | +from pydantic.fields import SHAPE_SINGLETON |
28 | 29 | from pydantic.fields import FieldInfo as PydanticFieldInfo |
29 | 30 | from pydantic.fields import ModelField, Undefined, UndefinedType |
30 | 31 | from pydantic.main import ModelMetaclass, validate_model |
@@ -424,14 +425,14 @@ def get_column_from_field(field: ModelField) -> Column: # type: ignore |
424 | 425 | return sa_column |
425 | 426 | sa_type = get_sqlachemy_type(field) |
426 | 427 | primary_key = getattr(field.field_info, "primary_key", False) |
427 | | - nullable = not field.required |
428 | 428 | index = getattr(field.field_info, "index", Undefined) |
429 | 429 | if index is Undefined: |
430 | 430 | index = False |
431 | 431 | if hasattr(field.field_info, "nullable"): |
432 | 432 | field_nullable = getattr(field.field_info, "nullable") |
433 | 433 | if field_nullable != Undefined: |
434 | 434 | nullable = field_nullable |
| 435 | + nullable = not primary_key and _is_field_nullable(field) |
435 | 436 | args = [] |
436 | 437 | foreign_key = getattr(field.field_info, "foreign_key", None) |
437 | 438 | if foreign_key: |
@@ -646,3 +647,13 @@ def _calculate_keys( |
646 | 647 | @declared_attr # type: ignore |
647 | 648 | def __tablename__(cls) -> str: |
648 | 649 | return cls.__name__.lower() |
| 650 | + |
| 651 | + |
| 652 | +def _is_field_nullable(field: ModelField) -> bool: |
| 653 | + if not field.required: |
| 654 | + # Taken from [Pydantic](https://github.com/samuelcolvin/pydantic/blob/v1.8.2/pydantic/fields.py#L946-L947) |
| 655 | + is_optional = field.allow_none and ( |
| 656 | + field.shape != SHAPE_SINGLETON or not field.sub_fields |
| 657 | + ) |
| 658 | + return is_optional and field.default is None and field.default_factory is None |
| 659 | + return False |
0 commit comments