Prathamesh Sable commited on
Commit
3f55893
·
1 Parent(s): 4d0ed60

Shift to MySQL

Browse files
alembic.ini CHANGED
@@ -63,7 +63,6 @@ version_path_separator = os
63
  # are written from script.py.mako
64
  # output_encoding = utf-8
65
 
66
- # sqlalchemy.url = postgresql://admin:kMUY6qMLce2fwMiocvf3cjxJLyeAOR1y@dpg-cvs9ajeuk2gs739pi5b0-a.singapore-postgres.render.com/food_analyzer_db
67
  sqlalchemy.url =
68
 
69
  [post_write_hooks]
 
63
  # are written from script.py.mako
64
  # output_encoding = utf-8
65
 
 
66
  sqlalchemy.url =
67
 
68
  [post_write_hooks]
db/models.py CHANGED
@@ -1,4 +1,4 @@
1
- from sqlalchemy import Column, Integer, String, Boolean, Text, JSON, ForeignKey, DateTime
2
  from sqlalchemy.orm import relationship, Mapped, mapped_column
3
  from sqlalchemy.sql import func
4
  from .database import Base
@@ -10,15 +10,16 @@ class Ingredient(Base):
10
  __tablename__ = "ingredients"
11
 
12
  id = Column(Integer, primary_key=True, index=True)
13
- name = Column(String, unique=True, index=True)
14
- alternate_names = Column(JSON, nullable=True)
15
  safety_rating = Column(Integer, nullable=True)
16
  description = Column(Text, nullable=True)
17
- health_effects = Column(JSON, nullable=True)
18
- allergic_info = Column(JSON, nullable=True)
19
- diet_type = Column(String, nullable=True)
20
- created_at = Column(DateTime(timezone=True), server_default=func.now())
21
- updated_at = Column(DateTime(timezone=True), onupdate=func.now())
 
22
 
23
  # Relationships
24
  sources = relationship("IngredientSource", back_populates="ingredient")
@@ -28,44 +29,46 @@ class IngredientSource(Base):
28
 
29
  id = Column(Integer, primary_key=True, index=True)
30
  ingredient_id = Column(Integer, ForeignKey("ingredients.id"))
31
- source_name = Column(String, nullable=False)
32
  found = Column(Boolean, default=False)
33
  summary = Column(Text, nullable=True)
34
- data = Column(JSON, nullable=True)
35
 
36
  # Relationships
37
  ingredient = relationship("Ingredient", back_populates="sources")
38
 
39
  class Marker(Base):
40
  __tablename__ = "markers"
41
- id: Mapped[int] = mapped_column(primary_key=True)
42
- image_name: Mapped[str]
43
- vuforia_id: Mapped[str]
44
- product_id: Mapped[int] = mapped_column(ForeignKey("products.id"))
45
-
46
- product: Mapped["Product"] = relationship(back_populates="markers")
47
 
 
 
 
48
  class Product(Base):
49
 
50
  __tablename__ = "products"
51
 
52
  id = Column(Integer, primary_key=True, index=True)
53
- product_name = Column(String, nullable=False)
54
- ingredients = Column(JSON, nullable=True)
55
- ingredients_analysis = Column(JSON, nullable=True)
56
  overall_safety_score = Column(Integer, nullable=True)
57
- suitable_diet_types = Column(String, nullable=True)
58
- allergy_warnings = Column(JSON, nullable=True)
59
- usage_recommendations = Column(String, nullable=True)
60
- health_insights = Column(JSON, nullable=True)
61
- ingredient_interactions = Column(JSON, nullable=True)
62
- key_takeaway = Column(String, nullable=True)
63
  ingredients_count = Column(Integer, nullable=True)
64
  user_id = Column(Integer, nullable=True)
65
  timestamp = Column(DateTime, nullable=True)
66
- ingredient_ids= Column(JSON, nullable=True)
67
 
68
- data_quality_warnings = Column(JSON, nullable=True)
69
  markers: Mapped[List["Marker"]] = relationship(back_populates="product")
70
 
71
 
@@ -73,9 +76,9 @@ class User(Base):
73
  __tablename__ = "users"
74
 
75
  id = Column(Integer, primary_key=True, index=True)
76
- name = Column(String, unique=False, index=False, nullable=False)
77
- email = Column(String, unique=True, index=True, nullable=False)
78
- hashed_password = Column(String, nullable=False)
79
  is_active = Column(Boolean, default=True)
80
 
81
  # Relationships
@@ -95,10 +98,10 @@ class UserPreferences(Base):
95
 
96
  id = Column(Integer, primary_key=True, index=True)
97
  user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"))
98
- dietary_restrictions = Column(String, nullable=True)
99
- allergens = Column(String, nullable=True)
100
- preferred_ingredients = Column(String, nullable=True)
101
- disliked_ingredients = Column(String, nullable=True)
102
 
103
  # Relationships
104
  user = relationship("User", back_populates="preferences")
 
1
+ from sqlalchemy import Column, Integer, String, Boolean, Text, JSON, ForeignKey, DateTime, text,TIMESTAMP
2
  from sqlalchemy.orm import relationship, Mapped, mapped_column
3
  from sqlalchemy.sql import func
4
  from .database import Base
 
10
  __tablename__ = "ingredients"
11
 
12
  id = Column(Integer, primary_key=True, index=True)
13
+ name = Column(String(255), unique=True, index=True)
14
+ alternate_names = Column(Text, nullable=True)
15
  safety_rating = Column(Integer, nullable=True)
16
  description = Column(Text, nullable=True)
17
+ health_effects = Column(Text, nullable=True)
18
+ allergic_info = Column(Text, nullable=True)
19
+ diet_type = Column(String(255), nullable=True)
20
+ # Fix the default timestamp for MySQL
21
+ created_at = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'))
22
+ updated_at = Column(DateTime(timezone=True),nullable=True)
23
 
24
  # Relationships
25
  sources = relationship("IngredientSource", back_populates="ingredient")
 
29
 
30
  id = Column(Integer, primary_key=True, index=True)
31
  ingredient_id = Column(Integer, ForeignKey("ingredients.id"))
32
+ source_name = Column(String(255), nullable=False)
33
  found = Column(Boolean, default=False)
34
  summary = Column(Text, nullable=True)
35
+ data = Column(Text, nullable=True)
36
 
37
  # Relationships
38
  ingredient = relationship("Ingredient", back_populates="sources")
39
 
40
  class Marker(Base):
41
  __tablename__ = "markers"
42
+
43
+ id = Column(Integer, primary_key=True, index=True)
44
+ image_name = Column(String(255), nullable=False)
45
+ vuforia_id = Column(String(255), nullable=False)
46
+ product_id = Column(Integer, ForeignKey("products.id"))
 
47
 
48
+ # Traditional relationship syntax
49
+ product = relationship("Product", back_populates="markers")
50
+
51
  class Product(Base):
52
 
53
  __tablename__ = "products"
54
 
55
  id = Column(Integer, primary_key=True, index=True)
56
+ product_name = Column(String(255), nullable=False)
57
+ ingredients = Column(Text, nullable=True)
58
+ ingredients_analysis = Column(Text, nullable=True)
59
  overall_safety_score = Column(Integer, nullable=True)
60
+ suitable_diet_types = Column(String(255), nullable=True)
61
+ allergy_warnings = Column(Text, nullable=True)
62
+ usage_recommendations = Column(Text, nullable=True)
63
+ health_insights = Column(Text, nullable=True)
64
+ ingredient_interactions = Column(Text, nullable=True)
65
+ key_takeaway = Column(Text, nullable=True)
66
  ingredients_count = Column(Integer, nullable=True)
67
  user_id = Column(Integer, nullable=True)
68
  timestamp = Column(DateTime, nullable=True)
69
+ ingredient_ids= Column(Text, nullable=True)
70
 
71
+ data_quality_warnings = Column(Text, nullable=True)
72
  markers: Mapped[List["Marker"]] = relationship(back_populates="product")
73
 
74
 
 
76
  __tablename__ = "users"
77
 
78
  id = Column(Integer, primary_key=True, index=True)
79
+ name = Column(String(255), unique=False, index=False, nullable=False)
80
+ email = Column(String(255), unique=True, index=True, nullable=False)
81
+ hashed_password = Column(String(255), nullable=False)
82
  is_active = Column(Boolean, default=True)
83
 
84
  # Relationships
 
98
 
99
  id = Column(Integer, primary_key=True, index=True)
100
  user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"))
101
+ dietary_restrictions = Column(String(255), nullable=True)
102
+ allergens = Column(Text, nullable=True)
103
+ preferred_ingredients = Column(Text, nullable=True)
104
+ disliked_ingredients = Column(Text, nullable=True)
105
 
106
  # Relationships
107
  user = relationship("User", back_populates="preferences")
migrations/versions/37b8cf50d624_updated_db.py ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """updated DB
2
+
3
+ Revision ID: 37b8cf50d624
4
+ Revises: a02cd287eec0
5
+ Create Date: 2025-05-09 11:09:49.317918
6
+
7
+ """
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision: str = '37b8cf50d624'
16
+ down_revision: Union[str, None] = 'a02cd287eec0'
17
+ branch_labels: Union[str, Sequence[str], None] = None
18
+ depends_on: Union[str, Sequence[str], None] = None
19
+
20
+
21
+ def upgrade() -> None:
22
+ """Upgrade schema."""
23
+ # ### commands auto generated by Alembic - please adjust! ###
24
+ op.create_table('markers',
25
+ sa.Column('id', sa.Integer(), nullable=False),
26
+ sa.Column('image_name', sa.String(length=255), nullable=False),
27
+ sa.Column('vuforia_id', sa.String(length=255), nullable=False),
28
+ sa.Column('product_id', sa.Integer(), nullable=True),
29
+ sa.ForeignKeyConstraint(['product_id'], ['products.id'], ),
30
+ sa.PrimaryKeyConstraint('id')
31
+ )
32
+ op.create_index(op.f('ix_markers_id'), 'markers', ['id'], unique=False)
33
+ op.create_table('scan_history',
34
+ sa.Column('id', sa.Integer(), nullable=False),
35
+ sa.Column('user_id', sa.Integer(), nullable=True),
36
+ sa.Column('product_id', sa.Integer(), nullable=True),
37
+ sa.Column('scan_date', sa.DateTime(), nullable=True),
38
+ sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
39
+ sa.PrimaryKeyConstraint('id')
40
+ )
41
+ op.create_index(op.f('ix_scan_history_id'), 'scan_history', ['id'], unique=False)
42
+ op.create_table('user_preferences',
43
+ sa.Column('id', sa.Integer(), nullable=False),
44
+ sa.Column('user_id', sa.Integer(), nullable=True),
45
+ sa.Column('dietary_restrictions', sa.String(length=255), nullable=True),
46
+ sa.Column('allergens', sa.Text(), nullable=True),
47
+ sa.Column('preferred_ingredients', sa.Text(), nullable=True),
48
+ sa.Column('disliked_ingredients', sa.Text(), nullable=True),
49
+ sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
50
+ sa.PrimaryKeyConstraint('id')
51
+ )
52
+ op.create_index(op.f('ix_user_preferences_id'), 'user_preferences', ['id'], unique=False)
53
+ # ### end Alembic commands ###
54
+
55
+
56
+ def downgrade() -> None:
57
+ """Downgrade schema."""
58
+ # ### commands auto generated by Alembic - please adjust! ###
59
+ op.drop_index(op.f('ix_user_preferences_id'), table_name='user_preferences')
60
+ op.drop_table('user_preferences')
61
+ op.drop_index(op.f('ix_scan_history_id'), table_name='scan_history')
62
+ op.drop_table('scan_history')
63
+ op.drop_index(op.f('ix_markers_id'), table_name='markers')
64
+ op.drop_table('markers')
65
+ # ### end Alembic commands ###
migrations/versions/464bdc8c474f_updated_db.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """updated DB
2
+
3
+ Revision ID: 464bdc8c474f
4
+ Revises: f4c75c169cf2
5
+ Create Date: 2025-05-09 10:33:17.799071
6
+
7
+ """
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision: str = '464bdc8c474f'
16
+ down_revision: Union[str, None] = 'f4c75c169cf2'
17
+ branch_labels: Union[str, Sequence[str], None] = None
18
+ depends_on: Union[str, Sequence[str], None] = None
19
+
20
+
21
+ def upgrade() -> None:
22
+ """Upgrade schema."""
23
+ # ### commands auto generated by Alembic - please adjust! ###
24
+ op.create_table('ingredients',
25
+ sa.Column('id', sa.Integer(), nullable=False),
26
+ sa.Column('name', sa.String(length=255), nullable=True),
27
+ sa.Column('alternate_names', sa.JSON(), nullable=True),
28
+ sa.Column('safety_rating', sa.Integer(), nullable=True),
29
+ sa.Column('description', sa.Text(), nullable=True),
30
+ sa.Column('health_effects', sa.JSON(), nullable=True),
31
+ sa.Column('allergic_info', sa.JSON(), nullable=True),
32
+ sa.Column('diet_type', sa.String(length=255), nullable=True),
33
+ sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
34
+ sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
35
+ sa.PrimaryKeyConstraint('id')
36
+ )
37
+ op.create_index(op.f('ix_ingredients_id'), 'ingredients', ['id'], unique=False)
38
+ op.create_index(op.f('ix_ingredients_name'), 'ingredients', ['name'], unique=True)
39
+ op.create_table('products',
40
+ sa.Column('id', sa.Integer(), nullable=False),
41
+ sa.Column('product_name', sa.String(length=255), nullable=False),
42
+ sa.Column('ingredients', sa.JSON(), nullable=True),
43
+ sa.Column('ingredients_analysis', sa.JSON(), nullable=True),
44
+ sa.Column('overall_safety_score', sa.Integer(), nullable=True),
45
+ sa.Column('suitable_diet_types', sa.String(length=255), nullable=True),
46
+ sa.Column('allergy_warnings', sa.JSON(), nullable=True),
47
+ sa.Column('usage_recommendations', sa.Text(), nullable=True),
48
+ sa.Column('health_insights', sa.JSON(), nullable=True),
49
+ sa.Column('ingredient_interactions', sa.JSON(), nullable=True),
50
+ sa.Column('key_takeaway', sa.Text(), nullable=True),
51
+ sa.Column('ingredients_count', sa.Integer(), nullable=True),
52
+ sa.Column('user_id', sa.Integer(), nullable=True),
53
+ sa.Column('timestamp', sa.DateTime(), nullable=True),
54
+ sa.Column('ingredient_ids', sa.JSON(), nullable=True),
55
+ sa.Column('data_quality_warnings', sa.JSON(), nullable=True),
56
+ sa.PrimaryKeyConstraint('id')
57
+ )
58
+ op.create_index(op.f('ix_products_id'), 'products', ['id'], unique=False)
59
+ op.create_table('users',
60
+ sa.Column('id', sa.Integer(), nullable=False),
61
+ sa.Column('name', sa.String(length=255), nullable=False),
62
+ sa.Column('email', sa.String(length=255), nullable=False),
63
+ sa.Column('hashed_password', sa.String(length=255), nullable=False),
64
+ sa.Column('is_active', sa.Boolean(), nullable=True),
65
+ sa.PrimaryKeyConstraint('id')
66
+ )
67
+ op.create_index(op.f('ix_users_email'), 'users', ['email'], unique=True)
68
+ op.create_index(op.f('ix_users_id'), 'users', ['id'], unique=False)
69
+ op.create_table('ingredient_sources',
70
+ sa.Column('id', sa.Integer(), nullable=False),
71
+ sa.Column('ingredient_id', sa.Integer(), nullable=True),
72
+ sa.Column('source_name', sa.String(length=255), nullable=False),
73
+ sa.Column('found', sa.Boolean(), nullable=True),
74
+ sa.Column('summary', sa.Text(), nullable=True),
75
+ sa.Column('data', sa.JSON(), nullable=True),
76
+ sa.ForeignKeyConstraint(['ingredient_id'], ['ingredients.id'], ),
77
+ sa.PrimaryKeyConstraint('id')
78
+ )
79
+ op.create_index(op.f('ix_ingredient_sources_id'), 'ingredient_sources', ['id'], unique=False)
80
+ op.create_table('markers',
81
+ sa.Column('id', sa.Integer(), nullable=False),
82
+ sa.Column('image_name', sa.String(), nullable=False),
83
+ sa.Column('vuforia_id', sa.String(), nullable=False),
84
+ sa.Column('product_id', sa.Integer(), nullable=False),
85
+ sa.ForeignKeyConstraint(['product_id'], ['products.id'], ),
86
+ sa.PrimaryKeyConstraint('id')
87
+ )
88
+ op.create_table('scan_history',
89
+ sa.Column('id', sa.Integer(), nullable=False),
90
+ sa.Column('user_id', sa.Integer(), nullable=True),
91
+ sa.Column('product_id', sa.Integer(), nullable=True),
92
+ sa.Column('scan_date', sa.DateTime(), nullable=True),
93
+ sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
94
+ sa.PrimaryKeyConstraint('id')
95
+ )
96
+ op.create_index(op.f('ix_scan_history_id'), 'scan_history', ['id'], unique=False)
97
+ op.create_table('user_preferences',
98
+ sa.Column('id', sa.Integer(), nullable=False),
99
+ sa.Column('user_id', sa.Integer(), nullable=True),
100
+ sa.Column('dietary_restrictions', sa.String(length=255), nullable=True),
101
+ sa.Column('allergens', sa.Text(), nullable=True),
102
+ sa.Column('preferred_ingredients', sa.Text(), nullable=True),
103
+ sa.Column('disliked_ingredients', sa.Text(), nullable=True),
104
+ sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
105
+ sa.PrimaryKeyConstraint('id')
106
+ )
107
+ op.create_index(op.f('ix_user_preferences_id'), 'user_preferences', ['id'], unique=False)
108
+ # ### end Alembic commands ###
109
+
110
+
111
+ def downgrade() -> None:
112
+ """Downgrade schema."""
113
+ # ### commands auto generated by Alembic - please adjust! ###
114
+ op.drop_index(op.f('ix_user_preferences_id'), table_name='user_preferences')
115
+ op.drop_table('user_preferences')
116
+ op.drop_index(op.f('ix_scan_history_id'), table_name='scan_history')
117
+ op.drop_table('scan_history')
118
+ op.drop_table('markers')
119
+ op.drop_index(op.f('ix_ingredient_sources_id'), table_name='ingredient_sources')
120
+ op.drop_table('ingredient_sources')
121
+ op.drop_index(op.f('ix_users_id'), table_name='users')
122
+ op.drop_index(op.f('ix_users_email'), table_name='users')
123
+ op.drop_table('users')
124
+ op.drop_index(op.f('ix_products_id'), table_name='products')
125
+ op.drop_table('products')
126
+ op.drop_index(op.f('ix_ingredients_name'), table_name='ingredients')
127
+ op.drop_index(op.f('ix_ingredients_id'), table_name='ingredients')
128
+ op.drop_table('ingredients')
129
+ # ### end Alembic commands ###
migrations/versions/50e02fec4154_updated_db.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """updated DB
2
+
3
+ Revision ID: 50e02fec4154
4
+ Revises: 00248bed0fb5
5
+ Create Date: 2025-05-09 09:59:35.961528
6
+
7
+ """
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision: str = '50e02fec4154'
16
+ down_revision: Union[str, None] = '00248bed0fb5'
17
+ branch_labels: Union[str, Sequence[str], None] = None
18
+ depends_on: Union[str, Sequence[str], None] = None
19
+
20
+
21
+ def upgrade() -> None:
22
+ """Upgrade schema."""
23
+ # ### commands auto generated by Alembic - please adjust! ###
24
+ pass
25
+ # ### end Alembic commands ###
26
+
27
+
28
+ def downgrade() -> None:
29
+ """Downgrade schema."""
30
+ # ### commands auto generated by Alembic - please adjust! ###
31
+ pass
32
+ # ### end Alembic commands ###
migrations/versions/579f1cd42a8f_updated_db.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """updated DB
2
+
3
+ Revision ID: 579f1cd42a8f
4
+ Revises: f8aa9e5882a2
5
+ Create Date: 2025-05-09 10:40:30.132328
6
+
7
+ """
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision: str = '579f1cd42a8f'
16
+ down_revision: Union[str, None] = 'f8aa9e5882a2'
17
+ branch_labels: Union[str, Sequence[str], None] = None
18
+ depends_on: Union[str, Sequence[str], None] = None
19
+
20
+
21
+ def upgrade() -> None:
22
+ """Upgrade schema."""
23
+ # ### commands auto generated by Alembic - please adjust! ###
24
+ op.create_table('ingredients',
25
+ sa.Column('id', sa.Integer(), nullable=False),
26
+ sa.Column('name', sa.String(length=255), nullable=True),
27
+ sa.Column('alternate_names', sa.Text(), nullable=True),
28
+ sa.Column('safety_rating', sa.Integer(), nullable=True),
29
+ sa.Column('description', sa.Text(), nullable=True),
30
+ sa.Column('health_effects', sa.Text(), nullable=True),
31
+ sa.Column('allergic_info', sa.Text(), nullable=True),
32
+ sa.Column('diet_type', sa.String(length=255), nullable=True),
33
+ sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True),
34
+ sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
35
+ sa.PrimaryKeyConstraint('id')
36
+ )
37
+ op.create_index(op.f('ix_ingredients_id'), 'ingredients', ['id'], unique=False)
38
+ op.create_index(op.f('ix_ingredients_name'), 'ingredients', ['name'], unique=True)
39
+ op.create_table('products',
40
+ sa.Column('id', sa.Integer(), nullable=False),
41
+ sa.Column('product_name', sa.String(length=255), nullable=False),
42
+ sa.Column('ingredients', sa.Text(), nullable=True),
43
+ sa.Column('ingredients_analysis', sa.Text(), nullable=True),
44
+ sa.Column('overall_safety_score', sa.Integer(), nullable=True),
45
+ sa.Column('suitable_diet_types', sa.String(length=255), nullable=True),
46
+ sa.Column('allergy_warnings', sa.Text(), nullable=True),
47
+ sa.Column('usage_recommendations', sa.Text(), nullable=True),
48
+ sa.Column('health_insights', sa.Text(), nullable=True),
49
+ sa.Column('ingredient_interactions', sa.Text(), nullable=True),
50
+ sa.Column('key_takeaway', sa.Text(), nullable=True),
51
+ sa.Column('ingredients_count', sa.Integer(), nullable=True),
52
+ sa.Column('user_id', sa.Integer(), nullable=True),
53
+ sa.Column('timestamp', sa.DateTime(), nullable=True),
54
+ sa.Column('ingredient_ids', sa.Text(), nullable=True),
55
+ sa.Column('data_quality_warnings', sa.Text(), nullable=True),
56
+ sa.PrimaryKeyConstraint('id')
57
+ )
58
+ op.create_index(op.f('ix_products_id'), 'products', ['id'], unique=False)
59
+ op.create_table('users',
60
+ sa.Column('id', sa.Integer(), nullable=False),
61
+ sa.Column('name', sa.String(length=255), nullable=False),
62
+ sa.Column('email', sa.String(length=255), nullable=False),
63
+ sa.Column('hashed_password', sa.String(length=255), nullable=False),
64
+ sa.Column('is_active', sa.Boolean(), nullable=True),
65
+ sa.PrimaryKeyConstraint('id')
66
+ )
67
+ op.create_index(op.f('ix_users_email'), 'users', ['email'], unique=True)
68
+ op.create_index(op.f('ix_users_id'), 'users', ['id'], unique=False)
69
+ op.create_table('ingredient_sources',
70
+ sa.Column('id', sa.Integer(), nullable=False),
71
+ sa.Column('ingredient_id', sa.Integer(), nullable=True),
72
+ sa.Column('source_name', sa.String(length=255), nullable=False),
73
+ sa.Column('found', sa.Boolean(), nullable=True),
74
+ sa.Column('summary', sa.Text(), nullable=True),
75
+ sa.Column('data', sa.Text(), nullable=True),
76
+ sa.ForeignKeyConstraint(['ingredient_id'], ['ingredients.id'], ),
77
+ sa.PrimaryKeyConstraint('id')
78
+ )
79
+ op.create_index(op.f('ix_ingredient_sources_id'), 'ingredient_sources', ['id'], unique=False)
80
+ op.create_table('markers',
81
+ sa.Column('id', sa.Integer(), nullable=False),
82
+ sa.Column('image_name', sa.String(), nullable=False),
83
+ sa.Column('vuforia_id', sa.String(), nullable=False),
84
+ sa.Column('product_id', sa.Integer(), nullable=False),
85
+ sa.ForeignKeyConstraint(['product_id'], ['products.id'], ),
86
+ sa.PrimaryKeyConstraint('id')
87
+ )
88
+ op.create_table('scan_history',
89
+ sa.Column('id', sa.Integer(), nullable=False),
90
+ sa.Column('user_id', sa.Integer(), nullable=True),
91
+ sa.Column('product_id', sa.Integer(), nullable=True),
92
+ sa.Column('scan_date', sa.DateTime(), nullable=True),
93
+ sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
94
+ sa.PrimaryKeyConstraint('id')
95
+ )
96
+ op.create_index(op.f('ix_scan_history_id'), 'scan_history', ['id'], unique=False)
97
+ op.create_table('user_preferences',
98
+ sa.Column('id', sa.Integer(), nullable=False),
99
+ sa.Column('user_id', sa.Integer(), nullable=True),
100
+ sa.Column('dietary_restrictions', sa.String(length=255), nullable=True),
101
+ sa.Column('allergens', sa.Text(), nullable=True),
102
+ sa.Column('preferred_ingredients', sa.Text(), nullable=True),
103
+ sa.Column('disliked_ingredients', sa.Text(), nullable=True),
104
+ sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
105
+ sa.PrimaryKeyConstraint('id')
106
+ )
107
+ op.create_index(op.f('ix_user_preferences_id'), 'user_preferences', ['id'], unique=False)
108
+ # ### end Alembic commands ###
109
+
110
+
111
+ def downgrade() -> None:
112
+ """Downgrade schema."""
113
+ # ### commands auto generated by Alembic - please adjust! ###
114
+ op.drop_index(op.f('ix_user_preferences_id'), table_name='user_preferences')
115
+ op.drop_table('user_preferences')
116
+ op.drop_index(op.f('ix_scan_history_id'), table_name='scan_history')
117
+ op.drop_table('scan_history')
118
+ op.drop_table('markers')
119
+ op.drop_index(op.f('ix_ingredient_sources_id'), table_name='ingredient_sources')
120
+ op.drop_table('ingredient_sources')
121
+ op.drop_index(op.f('ix_users_id'), table_name='users')
122
+ op.drop_index(op.f('ix_users_email'), table_name='users')
123
+ op.drop_table('users')
124
+ op.drop_index(op.f('ix_products_id'), table_name='products')
125
+ op.drop_table('products')
126
+ op.drop_index(op.f('ix_ingredients_name'), table_name='ingredients')
127
+ op.drop_index(op.f('ix_ingredients_id'), table_name='ingredients')
128
+ op.drop_table('ingredients')
129
+ # ### end Alembic commands ###
migrations/versions/6ea4e5e4de4d_updated_db.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """updated DB
2
+
3
+ Revision ID: 6ea4e5e4de4d
4
+ Revises: 579f1cd42a8f
5
+ Create Date: 2025-05-09 10:48:51.119673
6
+
7
+ """
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision: str = '6ea4e5e4de4d'
16
+ down_revision: Union[str, None] = '579f1cd42a8f'
17
+ branch_labels: Union[str, Sequence[str], None] = None
18
+ depends_on: Union[str, Sequence[str], None] = None
19
+
20
+
21
+ def upgrade() -> None:
22
+ """Upgrade schema."""
23
+ # ### commands auto generated by Alembic - please adjust! ###
24
+ op.create_table('ingredients',
25
+ sa.Column('id', sa.Integer(), nullable=False),
26
+ sa.Column('name', sa.String(length=255), nullable=True),
27
+ sa.Column('alternate_names', sa.Text(), nullable=True),
28
+ sa.Column('safety_rating', sa.Integer(), nullable=True),
29
+ sa.Column('description', sa.Text(), nullable=True),
30
+ sa.Column('health_effects', sa.Text(), nullable=True),
31
+ sa.Column('allergic_info', sa.Text(), nullable=True),
32
+ sa.Column('diet_type', sa.String(length=255), nullable=True),
33
+ sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=True),
34
+ sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=True),
35
+ sa.PrimaryKeyConstraint('id')
36
+ )
37
+ op.create_index(op.f('ix_ingredients_id'), 'ingredients', ['id'], unique=False)
38
+ op.create_index(op.f('ix_ingredients_name'), 'ingredients', ['name'], unique=True)
39
+ op.create_table('products',
40
+ sa.Column('id', sa.Integer(), nullable=False),
41
+ sa.Column('product_name', sa.String(length=255), nullable=False),
42
+ sa.Column('ingredients', sa.Text(), nullable=True),
43
+ sa.Column('ingredients_analysis', sa.Text(), nullable=True),
44
+ sa.Column('overall_safety_score', sa.Integer(), nullable=True),
45
+ sa.Column('suitable_diet_types', sa.String(length=255), nullable=True),
46
+ sa.Column('allergy_warnings', sa.Text(), nullable=True),
47
+ sa.Column('usage_recommendations', sa.Text(), nullable=True),
48
+ sa.Column('health_insights', sa.Text(), nullable=True),
49
+ sa.Column('ingredient_interactions', sa.Text(), nullable=True),
50
+ sa.Column('key_takeaway', sa.Text(), nullable=True),
51
+ sa.Column('ingredients_count', sa.Integer(), nullable=True),
52
+ sa.Column('user_id', sa.Integer(), nullable=True),
53
+ sa.Column('timestamp', sa.DateTime(), nullable=True),
54
+ sa.Column('ingredient_ids', sa.Text(), nullable=True),
55
+ sa.Column('data_quality_warnings', sa.Text(), nullable=True),
56
+ sa.PrimaryKeyConstraint('id')
57
+ )
58
+ op.create_index(op.f('ix_products_id'), 'products', ['id'], unique=False)
59
+ op.create_table('users',
60
+ sa.Column('id', sa.Integer(), nullable=False),
61
+ sa.Column('name', sa.String(length=255), nullable=False),
62
+ sa.Column('email', sa.String(length=255), nullable=False),
63
+ sa.Column('hashed_password', sa.String(length=255), nullable=False),
64
+ sa.Column('is_active', sa.Boolean(), nullable=True),
65
+ sa.PrimaryKeyConstraint('id')
66
+ )
67
+ op.create_index(op.f('ix_users_email'), 'users', ['email'], unique=True)
68
+ op.create_index(op.f('ix_users_id'), 'users', ['id'], unique=False)
69
+ op.create_table('ingredient_sources',
70
+ sa.Column('id', sa.Integer(), nullable=False),
71
+ sa.Column('ingredient_id', sa.Integer(), nullable=True),
72
+ sa.Column('source_name', sa.String(length=255), nullable=False),
73
+ sa.Column('found', sa.Boolean(), nullable=True),
74
+ sa.Column('summary', sa.Text(), nullable=True),
75
+ sa.Column('data', sa.Text(), nullable=True),
76
+ sa.ForeignKeyConstraint(['ingredient_id'], ['ingredients.id'], ),
77
+ sa.PrimaryKeyConstraint('id')
78
+ )
79
+ op.create_index(op.f('ix_ingredient_sources_id'), 'ingredient_sources', ['id'], unique=False)
80
+ op.create_table('markers',
81
+ sa.Column('id', sa.Integer(), nullable=False),
82
+ sa.Column('image_name', sa.String(), nullable=False),
83
+ sa.Column('vuforia_id', sa.String(), nullable=False),
84
+ sa.Column('product_id', sa.Integer(), nullable=False),
85
+ sa.ForeignKeyConstraint(['product_id'], ['products.id'], ),
86
+ sa.PrimaryKeyConstraint('id')
87
+ )
88
+ op.create_table('scan_history',
89
+ sa.Column('id', sa.Integer(), nullable=False),
90
+ sa.Column('user_id', sa.Integer(), nullable=True),
91
+ sa.Column('product_id', sa.Integer(), nullable=True),
92
+ sa.Column('scan_date', sa.DateTime(), nullable=True),
93
+ sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
94
+ sa.PrimaryKeyConstraint('id')
95
+ )
96
+ op.create_index(op.f('ix_scan_history_id'), 'scan_history', ['id'], unique=False)
97
+ op.create_table('user_preferences',
98
+ sa.Column('id', sa.Integer(), nullable=False),
99
+ sa.Column('user_id', sa.Integer(), nullable=True),
100
+ sa.Column('dietary_restrictions', sa.String(length=255), nullable=True),
101
+ sa.Column('allergens', sa.Text(), nullable=True),
102
+ sa.Column('preferred_ingredients', sa.Text(), nullable=True),
103
+ sa.Column('disliked_ingredients', sa.Text(), nullable=True),
104
+ sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
105
+ sa.PrimaryKeyConstraint('id')
106
+ )
107
+ op.create_index(op.f('ix_user_preferences_id'), 'user_preferences', ['id'], unique=False)
108
+ # ### end Alembic commands ###
109
+
110
+
111
+ def downgrade() -> None:
112
+ """Downgrade schema."""
113
+ # ### commands auto generated by Alembic - please adjust! ###
114
+ op.drop_index(op.f('ix_user_preferences_id'), table_name='user_preferences')
115
+ op.drop_table('user_preferences')
116
+ op.drop_index(op.f('ix_scan_history_id'), table_name='scan_history')
117
+ op.drop_table('scan_history')
118
+ op.drop_table('markers')
119
+ op.drop_index(op.f('ix_ingredient_sources_id'), table_name='ingredient_sources')
120
+ op.drop_table('ingredient_sources')
121
+ op.drop_index(op.f('ix_users_id'), table_name='users')
122
+ op.drop_index(op.f('ix_users_email'), table_name='users')
123
+ op.drop_table('users')
124
+ op.drop_index(op.f('ix_products_id'), table_name='products')
125
+ op.drop_table('products')
126
+ op.drop_index(op.f('ix_ingredients_name'), table_name='ingredients')
127
+ op.drop_index(op.f('ix_ingredients_id'), table_name='ingredients')
128
+ op.drop_table('ingredients')
129
+ # ### end Alembic commands ###
migrations/versions/a02cd287eec0_updated_db.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """updated DB
2
+
3
+ Revision ID: a02cd287eec0
4
+ Revises: 6ea4e5e4de4d
5
+ Create Date: 2025-05-09 11:03:43.504573
6
+
7
+ """
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision: str = 'a02cd287eec0'
16
+ down_revision: Union[str, None] = '6ea4e5e4de4d'
17
+ branch_labels: Union[str, Sequence[str], None] = None
18
+ depends_on: Union[str, Sequence[str], None] = None
19
+
20
+
21
+ def upgrade() -> None:
22
+ """Upgrade schema."""
23
+ # ### commands auto generated by Alembic - please adjust! ###
24
+ op.create_table('ingredients',
25
+ sa.Column('id', sa.Integer(), nullable=False),
26
+ sa.Column('name', sa.String(length=255), nullable=True),
27
+ sa.Column('alternate_names', sa.Text(), nullable=True),
28
+ sa.Column('safety_rating', sa.Integer(), nullable=True),
29
+ sa.Column('description', sa.Text(), nullable=True),
30
+ sa.Column('health_effects', sa.Text(), nullable=True),
31
+ sa.Column('allergic_info', sa.Text(), nullable=True),
32
+ sa.Column('diet_type', sa.String(length=255), nullable=True),
33
+ sa.Column('created_at', sa.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True),
34
+ sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
35
+ sa.PrimaryKeyConstraint('id')
36
+ )
37
+ op.create_index(op.f('ix_ingredients_id'), 'ingredients', ['id'], unique=False)
38
+ op.create_index(op.f('ix_ingredients_name'), 'ingredients', ['name'], unique=True)
39
+ op.create_table('products',
40
+ sa.Column('id', sa.Integer(), nullable=False),
41
+ sa.Column('product_name', sa.String(length=255), nullable=False),
42
+ sa.Column('ingredients', sa.Text(), nullable=True),
43
+ sa.Column('ingredients_analysis', sa.Text(), nullable=True),
44
+ sa.Column('overall_safety_score', sa.Integer(), nullable=True),
45
+ sa.Column('suitable_diet_types', sa.String(length=255), nullable=True),
46
+ sa.Column('allergy_warnings', sa.Text(), nullable=True),
47
+ sa.Column('usage_recommendations', sa.Text(), nullable=True),
48
+ sa.Column('health_insights', sa.Text(), nullable=True),
49
+ sa.Column('ingredient_interactions', sa.Text(), nullable=True),
50
+ sa.Column('key_takeaway', sa.Text(), nullable=True),
51
+ sa.Column('ingredients_count', sa.Integer(), nullable=True),
52
+ sa.Column('user_id', sa.Integer(), nullable=True),
53
+ sa.Column('timestamp', sa.DateTime(), nullable=True),
54
+ sa.Column('ingredient_ids', sa.Text(), nullable=True),
55
+ sa.Column('data_quality_warnings', sa.Text(), nullable=True),
56
+ sa.PrimaryKeyConstraint('id')
57
+ )
58
+ op.create_index(op.f('ix_products_id'), 'products', ['id'], unique=False)
59
+ op.create_table('users',
60
+ sa.Column('id', sa.Integer(), nullable=False),
61
+ sa.Column('name', sa.String(length=255), nullable=False),
62
+ sa.Column('email', sa.String(length=255), nullable=False),
63
+ sa.Column('hashed_password', sa.String(length=255), nullable=False),
64
+ sa.Column('is_active', sa.Boolean(), nullable=True),
65
+ sa.PrimaryKeyConstraint('id')
66
+ )
67
+ op.create_index(op.f('ix_users_email'), 'users', ['email'], unique=True)
68
+ op.create_index(op.f('ix_users_id'), 'users', ['id'], unique=False)
69
+ op.create_table('ingredient_sources',
70
+ sa.Column('id', sa.Integer(), nullable=False),
71
+ sa.Column('ingredient_id', sa.Integer(), nullable=True),
72
+ sa.Column('source_name', sa.String(length=255), nullable=False),
73
+ sa.Column('found', sa.Boolean(), nullable=True),
74
+ sa.Column('summary', sa.Text(), nullable=True),
75
+ sa.Column('data', sa.Text(), nullable=True),
76
+ sa.ForeignKeyConstraint(['ingredient_id'], ['ingredients.id'], ),
77
+ sa.PrimaryKeyConstraint('id')
78
+ )
79
+ op.create_index(op.f('ix_ingredient_sources_id'), 'ingredient_sources', ['id'], unique=False)
80
+ op.create_table('markers',
81
+ sa.Column('id', sa.Integer(), nullable=False),
82
+ sa.Column('image_name', sa.String(), nullable=False),
83
+ sa.Column('vuforia_id', sa.String(), nullable=False),
84
+ sa.Column('product_id', sa.Integer(), nullable=False),
85
+ sa.ForeignKeyConstraint(['product_id'], ['products.id'], ),
86
+ sa.PrimaryKeyConstraint('id')
87
+ )
88
+ op.create_table('scan_history',
89
+ sa.Column('id', sa.Integer(), nullable=False),
90
+ sa.Column('user_id', sa.Integer(), nullable=True),
91
+ sa.Column('product_id', sa.Integer(), nullable=True),
92
+ sa.Column('scan_date', sa.DateTime(), nullable=True),
93
+ sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
94
+ sa.PrimaryKeyConstraint('id')
95
+ )
96
+ op.create_index(op.f('ix_scan_history_id'), 'scan_history', ['id'], unique=False)
97
+ op.create_table('user_preferences',
98
+ sa.Column('id', sa.Integer(), nullable=False),
99
+ sa.Column('user_id', sa.Integer(), nullable=True),
100
+ sa.Column('dietary_restrictions', sa.String(length=255), nullable=True),
101
+ sa.Column('allergens', sa.Text(), nullable=True),
102
+ sa.Column('preferred_ingredients', sa.Text(), nullable=True),
103
+ sa.Column('disliked_ingredients', sa.Text(), nullable=True),
104
+ sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
105
+ sa.PrimaryKeyConstraint('id')
106
+ )
107
+ op.create_index(op.f('ix_user_preferences_id'), 'user_preferences', ['id'], unique=False)
108
+ # ### end Alembic commands ###
109
+
110
+
111
+ def downgrade() -> None:
112
+ """Downgrade schema."""
113
+ # ### commands auto generated by Alembic - please adjust! ###
114
+ op.drop_index(op.f('ix_user_preferences_id'), table_name='user_preferences')
115
+ op.drop_table('user_preferences')
116
+ op.drop_index(op.f('ix_scan_history_id'), table_name='scan_history')
117
+ op.drop_table('scan_history')
118
+ op.drop_table('markers')
119
+ op.drop_index(op.f('ix_ingredient_sources_id'), table_name='ingredient_sources')
120
+ op.drop_table('ingredient_sources')
121
+ op.drop_index(op.f('ix_users_id'), table_name='users')
122
+ op.drop_index(op.f('ix_users_email'), table_name='users')
123
+ op.drop_table('users')
124
+ op.drop_index(op.f('ix_products_id'), table_name='products')
125
+ op.drop_table('products')
126
+ op.drop_index(op.f('ix_ingredients_name'), table_name='ingredients')
127
+ op.drop_index(op.f('ix_ingredients_id'), table_name='ingredients')
128
+ op.drop_table('ingredients')
129
+ # ### end Alembic commands ###
migrations/versions/f4c75c169cf2_updated_db.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """updated DB
2
+
3
+ Revision ID: f4c75c169cf2
4
+ Revises: 50e02fec4154
5
+ Create Date: 2025-05-09 10:27:47.732746
6
+
7
+ """
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision: str = 'f4c75c169cf2'
16
+ down_revision: Union[str, None] = '50e02fec4154'
17
+ branch_labels: Union[str, Sequence[str], None] = None
18
+ depends_on: Union[str, Sequence[str], None] = None
19
+
20
+
21
+ def upgrade() -> None:
22
+ """Upgrade schema."""
23
+ # ### commands auto generated by Alembic - please adjust! ###
24
+ op.create_table('ingredients',
25
+ sa.Column('id', sa.Integer(), nullable=False),
26
+ sa.Column('name', sa.String(), nullable=True),
27
+ sa.Column('alternate_names', sa.JSON(), nullable=True),
28
+ sa.Column('safety_rating', sa.Integer(), nullable=True),
29
+ sa.Column('description', sa.Text(), nullable=True),
30
+ sa.Column('health_effects', sa.JSON(), nullable=True),
31
+ sa.Column('allergic_info', sa.JSON(), nullable=True),
32
+ sa.Column('diet_type', sa.String(), nullable=True),
33
+ sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
34
+ sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
35
+ sa.PrimaryKeyConstraint('id')
36
+ )
37
+ op.create_index(op.f('ix_ingredients_id'), 'ingredients', ['id'], unique=False)
38
+ op.create_index(op.f('ix_ingredients_name'), 'ingredients', ['name'], unique=True)
39
+ op.create_table('products',
40
+ sa.Column('id', sa.Integer(), nullable=False),
41
+ sa.Column('product_name', sa.String(), nullable=False),
42
+ sa.Column('ingredients', sa.JSON(), nullable=True),
43
+ sa.Column('ingredients_analysis', sa.JSON(), nullable=True),
44
+ sa.Column('overall_safety_score', sa.Integer(), nullable=True),
45
+ sa.Column('suitable_diet_types', sa.String(), nullable=True),
46
+ sa.Column('allergy_warnings', sa.JSON(), nullable=True),
47
+ sa.Column('usage_recommendations', sa.String(), nullable=True),
48
+ sa.Column('health_insights', sa.JSON(), nullable=True),
49
+ sa.Column('ingredient_interactions', sa.JSON(), nullable=True),
50
+ sa.Column('key_takeaway', sa.String(), nullable=True),
51
+ sa.Column('ingredients_count', sa.Integer(), nullable=True),
52
+ sa.Column('user_id', sa.Integer(), nullable=True),
53
+ sa.Column('timestamp', sa.DateTime(), nullable=True),
54
+ sa.Column('ingredient_ids', sa.JSON(), nullable=True),
55
+ sa.Column('data_quality_warnings', sa.JSON(), nullable=True),
56
+ sa.PrimaryKeyConstraint('id')
57
+ )
58
+ op.create_index(op.f('ix_products_id'), 'products', ['id'], unique=False)
59
+ op.create_table('users',
60
+ sa.Column('id', sa.Integer(), nullable=False),
61
+ sa.Column('name', sa.String(), nullable=False),
62
+ sa.Column('email', sa.String(), nullable=False),
63
+ sa.Column('hashed_password', sa.String(), nullable=False),
64
+ sa.Column('is_active', sa.Boolean(), nullable=True),
65
+ sa.PrimaryKeyConstraint('id')
66
+ )
67
+ op.create_index(op.f('ix_users_email'), 'users', ['email'], unique=True)
68
+ op.create_index(op.f('ix_users_id'), 'users', ['id'], unique=False)
69
+ op.create_table('ingredient_sources',
70
+ sa.Column('id', sa.Integer(), nullable=False),
71
+ sa.Column('ingredient_id', sa.Integer(), nullable=True),
72
+ sa.Column('source_name', sa.String(), nullable=False),
73
+ sa.Column('found', sa.Boolean(), nullable=True),
74
+ sa.Column('summary', sa.Text(), nullable=True),
75
+ sa.Column('data', sa.JSON(), nullable=True),
76
+ sa.ForeignKeyConstraint(['ingredient_id'], ['ingredients.id'], ),
77
+ sa.PrimaryKeyConstraint('id')
78
+ )
79
+ op.create_index(op.f('ix_ingredient_sources_id'), 'ingredient_sources', ['id'], unique=False)
80
+ op.create_table('markers',
81
+ sa.Column('id', sa.Integer(), nullable=False),
82
+ sa.Column('image_name', sa.String(), nullable=False),
83
+ sa.Column('vuforia_id', sa.String(), nullable=False),
84
+ sa.Column('product_id', sa.Integer(), nullable=False),
85
+ sa.ForeignKeyConstraint(['product_id'], ['products.id'], ),
86
+ sa.PrimaryKeyConstraint('id')
87
+ )
88
+ op.create_table('scan_history',
89
+ sa.Column('id', sa.Integer(), nullable=False),
90
+ sa.Column('user_id', sa.Integer(), nullable=True),
91
+ sa.Column('product_id', sa.Integer(), nullable=True),
92
+ sa.Column('scan_date', sa.DateTime(), nullable=True),
93
+ sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
94
+ sa.PrimaryKeyConstraint('id')
95
+ )
96
+ op.create_index(op.f('ix_scan_history_id'), 'scan_history', ['id'], unique=False)
97
+ op.create_table('user_preferences',
98
+ sa.Column('id', sa.Integer(), nullable=False),
99
+ sa.Column('user_id', sa.Integer(), nullable=True),
100
+ sa.Column('dietary_restrictions', sa.String(), nullable=True),
101
+ sa.Column('allergens', sa.String(), nullable=True),
102
+ sa.Column('preferred_ingredients', sa.String(), nullable=True),
103
+ sa.Column('disliked_ingredients', sa.String(), nullable=True),
104
+ sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
105
+ sa.PrimaryKeyConstraint('id')
106
+ )
107
+ op.create_index(op.f('ix_user_preferences_id'), 'user_preferences', ['id'], unique=False)
108
+ # ### end Alembic commands ###
109
+
110
+
111
+ def downgrade() -> None:
112
+ """Downgrade schema."""
113
+ # ### commands auto generated by Alembic - please adjust! ###
114
+ op.drop_index(op.f('ix_user_preferences_id'), table_name='user_preferences')
115
+ op.drop_table('user_preferences')
116
+ op.drop_index(op.f('ix_scan_history_id'), table_name='scan_history')
117
+ op.drop_table('scan_history')
118
+ op.drop_table('markers')
119
+ op.drop_index(op.f('ix_ingredient_sources_id'), table_name='ingredient_sources')
120
+ op.drop_table('ingredient_sources')
121
+ op.drop_index(op.f('ix_users_id'), table_name='users')
122
+ op.drop_index(op.f('ix_users_email'), table_name='users')
123
+ op.drop_table('users')
124
+ op.drop_index(op.f('ix_products_id'), table_name='products')
125
+ op.drop_table('products')
126
+ op.drop_index(op.f('ix_ingredients_name'), table_name='ingredients')
127
+ op.drop_index(op.f('ix_ingredients_id'), table_name='ingredients')
128
+ op.drop_table('ingredients')
129
+ # ### end Alembic commands ###
migrations/versions/f8aa9e5882a2_updated_db.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """updated DB
2
+
3
+ Revision ID: f8aa9e5882a2
4
+ Revises: 464bdc8c474f
5
+ Create Date: 2025-05-09 10:36:18.602936
6
+
7
+ """
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision: str = 'f8aa9e5882a2'
16
+ down_revision: Union[str, None] = '464bdc8c474f'
17
+ branch_labels: Union[str, Sequence[str], None] = None
18
+ depends_on: Union[str, Sequence[str], None] = None
19
+
20
+
21
+ def upgrade() -> None:
22
+ """Upgrade schema."""
23
+ # ### commands auto generated by Alembic - please adjust! ###
24
+ op.create_table('ingredients',
25
+ sa.Column('id', sa.Integer(), nullable=False),
26
+ sa.Column('name', sa.String(length=255), nullable=True),
27
+ sa.Column('alternate_names', sa.Text(), nullable=True),
28
+ sa.Column('safety_rating', sa.Integer(), nullable=True),
29
+ sa.Column('description', sa.Text(), nullable=True),
30
+ sa.Column('health_effects', sa.Text(), nullable=True),
31
+ sa.Column('allergic_info', sa.Text(), nullable=True),
32
+ sa.Column('diet_type', sa.String(length=255), nullable=True),
33
+ sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
34
+ sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
35
+ sa.PrimaryKeyConstraint('id')
36
+ )
37
+ op.create_index(op.f('ix_ingredients_id'), 'ingredients', ['id'], unique=False)
38
+ op.create_index(op.f('ix_ingredients_name'), 'ingredients', ['name'], unique=True)
39
+ op.create_table('products',
40
+ sa.Column('id', sa.Integer(), nullable=False),
41
+ sa.Column('product_name', sa.String(length=255), nullable=False),
42
+ sa.Column('ingredients', sa.Text(), nullable=True),
43
+ sa.Column('ingredients_analysis', sa.Text(), nullable=True),
44
+ sa.Column('overall_safety_score', sa.Integer(), nullable=True),
45
+ sa.Column('suitable_diet_types', sa.String(length=255), nullable=True),
46
+ sa.Column('allergy_warnings', sa.Text(), nullable=True),
47
+ sa.Column('usage_recommendations', sa.Text(), nullable=True),
48
+ sa.Column('health_insights', sa.Text(), nullable=True),
49
+ sa.Column('ingredient_interactions', sa.Text(), nullable=True),
50
+ sa.Column('key_takeaway', sa.Text(), nullable=True),
51
+ sa.Column('ingredients_count', sa.Integer(), nullable=True),
52
+ sa.Column('user_id', sa.Integer(), nullable=True),
53
+ sa.Column('timestamp', sa.DateTime(), nullable=True),
54
+ sa.Column('ingredient_ids', sa.Text(), nullable=True),
55
+ sa.Column('data_quality_warnings', sa.Text(), nullable=True),
56
+ sa.PrimaryKeyConstraint('id')
57
+ )
58
+ op.create_index(op.f('ix_products_id'), 'products', ['id'], unique=False)
59
+ op.create_table('users',
60
+ sa.Column('id', sa.Integer(), nullable=False),
61
+ sa.Column('name', sa.String(length=255), nullable=False),
62
+ sa.Column('email', sa.String(length=255), nullable=False),
63
+ sa.Column('hashed_password', sa.String(length=255), nullable=False),
64
+ sa.Column('is_active', sa.Boolean(), nullable=True),
65
+ sa.PrimaryKeyConstraint('id')
66
+ )
67
+ op.create_index(op.f('ix_users_email'), 'users', ['email'], unique=True)
68
+ op.create_index(op.f('ix_users_id'), 'users', ['id'], unique=False)
69
+ op.create_table('ingredient_sources',
70
+ sa.Column('id', sa.Integer(), nullable=False),
71
+ sa.Column('ingredient_id', sa.Integer(), nullable=True),
72
+ sa.Column('source_name', sa.String(length=255), nullable=False),
73
+ sa.Column('found', sa.Boolean(), nullable=True),
74
+ sa.Column('summary', sa.Text(), nullable=True),
75
+ sa.Column('data', sa.Text(), nullable=True),
76
+ sa.ForeignKeyConstraint(['ingredient_id'], ['ingredients.id'], ),
77
+ sa.PrimaryKeyConstraint('id')
78
+ )
79
+ op.create_index(op.f('ix_ingredient_sources_id'), 'ingredient_sources', ['id'], unique=False)
80
+ op.create_table('markers',
81
+ sa.Column('id', sa.Integer(), nullable=False),
82
+ sa.Column('image_name', sa.String(), nullable=False),
83
+ sa.Column('vuforia_id', sa.String(), nullable=False),
84
+ sa.Column('product_id', sa.Integer(), nullable=False),
85
+ sa.ForeignKeyConstraint(['product_id'], ['products.id'], ),
86
+ sa.PrimaryKeyConstraint('id')
87
+ )
88
+ op.create_table('scan_history',
89
+ sa.Column('id', sa.Integer(), nullable=False),
90
+ sa.Column('user_id', sa.Integer(), nullable=True),
91
+ sa.Column('product_id', sa.Integer(), nullable=True),
92
+ sa.Column('scan_date', sa.DateTime(), nullable=True),
93
+ sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
94
+ sa.PrimaryKeyConstraint('id')
95
+ )
96
+ op.create_index(op.f('ix_scan_history_id'), 'scan_history', ['id'], unique=False)
97
+ op.create_table('user_preferences',
98
+ sa.Column('id', sa.Integer(), nullable=False),
99
+ sa.Column('user_id', sa.Integer(), nullable=True),
100
+ sa.Column('dietary_restrictions', sa.String(length=255), nullable=True),
101
+ sa.Column('allergens', sa.Text(), nullable=True),
102
+ sa.Column('preferred_ingredients', sa.Text(), nullable=True),
103
+ sa.Column('disliked_ingredients', sa.Text(), nullable=True),
104
+ sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
105
+ sa.PrimaryKeyConstraint('id')
106
+ )
107
+ op.create_index(op.f('ix_user_preferences_id'), 'user_preferences', ['id'], unique=False)
108
+ # ### end Alembic commands ###
109
+
110
+
111
+ def downgrade() -> None:
112
+ """Downgrade schema."""
113
+ # ### commands auto generated by Alembic - please adjust! ###
114
+ op.drop_index(op.f('ix_user_preferences_id'), table_name='user_preferences')
115
+ op.drop_table('user_preferences')
116
+ op.drop_index(op.f('ix_scan_history_id'), table_name='scan_history')
117
+ op.drop_table('scan_history')
118
+ op.drop_table('markers')
119
+ op.drop_index(op.f('ix_ingredient_sources_id'), table_name='ingredient_sources')
120
+ op.drop_table('ingredient_sources')
121
+ op.drop_index(op.f('ix_users_id'), table_name='users')
122
+ op.drop_index(op.f('ix_users_email'), table_name='users')
123
+ op.drop_table('users')
124
+ op.drop_index(op.f('ix_products_id'), table_name='products')
125
+ op.drop_table('products')
126
+ op.drop_index(op.f('ix_ingredients_name'), table_name='ingredients')
127
+ op.drop_index(op.f('ix_ingredients_id'), table_name='ingredients')
128
+ op.drop_table('ingredients')
129
+ # ### end Alembic commands ###