How to construct table in postgreSQL - python

__tablename__ = "user_ingredients"
ingred_id = db.Column(db.Integer, db.ForeignKey('ingredients.ingred_id'), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('users.user_id'), nullable=False)
ingred_id and user_id are variables in the class UserIngredient. How do i create the table user_ingredients in postgreSQL as im not sure how to do it when its like ingredients.ingred_id. On searching internet something about foreign keys was mentioned but this is first time im using postgreSQL so i dont know how to use that

What you are describing is a basic M:M relationship between tables USERS and INGREDIENTS. The table USER_INGREDIENTS the is the resolution between them. Any additional attributes then describe the particular attributes for a specific combination of user and ingredient.
create table users( user_id integer generated always as identity
, name text
--other columns
, constraint users_pk primary key (user_id)
);
create table ingredients( ingredient_id integer generated always as identity
, name text
--other columns
, constraint ingredients_pk primary key (ingredient_id)
);
create table user_ingredients( user_id integer
, ingredient_id integer
, quantity number -- for example
, measurement_type text -- for example
, quantity_description text -- for example
, constraint user_ingredients_pk
primary key (user_id, ingredient_id)
, constraint user_ingredients_2_user_fk
foreign key (user_id)
references users(user_id)
, constraint user_ingredients_2_ingredients_fk
foreign key (ingredients_id)
references ingredients(ingredients_id)
);
);
As indicated the above is pretty basic to any relational database. I suggest you invest some time ( references and tutorials) understanding them, even if you will only work with teem through an obfuscation (ORM) layer.

Related

SQLAlchemy Error '(psycopg2.errors.NotNullViolation) null value in column "id" of relation

I am aware of a similar issue How to fix error: (psycopg2.errors.NotNullViolation) null value in column "id" violates not-null constraint? but the answers there did not fix my error
I have the following sqlalchemy structure connected to a postgres database
class Injury(db.Model):
__tablename__ = "injury"
id = Column(Integer, primary_key=True)
name = Column(String)
description = Column(String)
The DDL looks like
create table injury
(
id bigint not null
constraint idx_182837_injury_pkey
primary key
constraint injury_id_key
unique,
name text,
description text,
);
However, upon trying to insert something into the database like the following
injury = Injury(name='name', description='desc')
session.add(injury)
session.commit()
The following error occurs
Error '(psycopg2.errors.NotNullViolation) null value in column "id" of relation "injury" violates not-null constraint
Upon opening up my debugger, I can verify that the id attribute in the injury object before I commit is None
Why is this occurring? Shouldn't primary_key=True in my schema tell postgres that it is responsible for making the id? I tried playing around with SEQUENCE and IDENTITY but I was getting the same error
you have to tell it to auto increment
dont use bigint but serial
id SERIAL PRIMARY KEY
check this how-to-define-an-auto-increment-primary-key-in-postgresql-using-python
This was a result of some form of bug during my transfer from sqlite to postgres when I used pg_loader. I found out someone else encountered this and I followed their instructions and it corrected my issue. The following steps were all done in IntelliJ's database tool
Exported all of my data out with pg_dump
Reformatted my id schema to look like id = Column(Integer, Identity(start=2116), primary_key=True) where 2116 is one more than the last id i currently have in my database
Reloaded data base in with pg_loader
This was working without the Identity field but the key was set to 1 instead of 2116. Looking at this article helped me realize I needed to use the Identity field.

How to fix 'Invalid input syntax for integer' issue while using sqlalchemy Declarative API

I'm actually building a little utils which aims to take flat csv/excel file and populate a target database on MS Access - as I'm working on a Mac, i'm developping it using Postgres...
So I developped a part which deals with messy input (csv/excel) forms (several heading, etc) but that's not my issue at the moment.
On the other hand, I made my Database model using SQLAlchemy Declarative Base API.
I'm facing issue when importing data in some tables:
- Split flat record to several objects
- Check (SELECT) if the record doesn't exists yet based on uniqueness contraints
- If it doesn't exists I create object else I use the existing one
- Propagate keys information to related object
For some tables I'm using the auto_increment arguments but sometimes the record has its own ID (in input file) so I should it for insert/select in my tables and sometimes no ID so I have to create a new technical Id for my table.
Example: I have a record with for primary key -obsr25644- and sometimes nothing so I use a default value created with uuid.
So below the stacktrace when doing selectoperation on a my table. The same error occurs when working on existing data - obsr25644 - and generated uuid - 'a8098c1a-f86e-11da-bd1a-00112444be1e'
sqlalchemy.exc.DataError: (psycopg2.errors.InvalidTextRepresentation) **invalid input syntax for integer**: "obsr25644"
LINE 3: WHERE "Location"."Id_observer" = 'obsr25644'
As you can see below, "Location"."Id_observer" is declared as String(255). I don't understand why the error is related to 'integer'.
[SQL: SELECT "Location"."Id_location" AS "Location_Id_location", [...], "Location"."Id_observer" AS "Location_Id_observer",
FROM "Location"
WHERE "Location"."Id_observer" = %(Id_observer_1)s
LIMIT %(param_1)s]
[parameters: {'Id_observer_1': 'obsr25644', 'param_1': 1}]
class LocationModel(UniqueMixin, Base):
__tablename__ = 'Location'
# Primary key
Id_location = Column(Integer, primary_key=True, autoincrement=True)
[...]
Id_observer = Column(String(255), ForeignKey('Observer.Id_observer'))
observer = relationship("ObserverModel", load_on_pending=True, back_populates="location")
class ObserverModel(UniqueMixin, Base):
__tablename__ = 'Observer'
# Primary key
Id_observer = Column(String(255), primary_key=True, default=UniqueMixin.unique_hash())
[...]
# Relationship
location = relationship("LocationModel", load_on_pending=True, back_populates="observer")
Note :UniqueMixin.unique_hash() returns uuid.uuid4().hex

sqlalchemy primary key without auto-increment

I'm trying to establish a table with a layout approximately like the following:
class Widget(db.Model):
__tablename__ = 'widgets'
ext_id = db.Column(db.Integer, primary_key=True)
w_code = db.Column(db.String(34), unique=True)
# other traits follow...
All field values are provided through an external system, and new Widgets are discovered and some of the omitted trait values may change over time (very gradually) but the ext_id and w_code are guaranteed to be unique. Given the nature of the values for ext_id it behaves ideally as a primary key.
However when I create a new record, specifying the ext_id value, the value is not used in storage. Instead the values in ext_id follow an auto-increment behavior.
>>> # from a clean database
>>> skill = Widget(ext_id=7723, w_code=u'IGF35ac9')
>>> session.add(skill)
>>> session.commit()
>>> Skill.query.first().ext_id
1
>>>
How can I specify to SQLAlchemy that the ext_id field should be used as the primary key field without auto-increment?
Note:
I could add an extra synthetic id column as the primary key and make ext_id be a unique column instead but this both complicates my code and adds a (minimal) extra bloat to the database and all I/O to it. I'm hoping to avoid that.
Issue originated from a larger project but I was able to create a smaller repro.
Testing with sqlite
Set autoincrement=False to disable creating a sequence or serial for the primary key.
ext_id = db.Column(db.Integer, primary_key=True, autoincrement=False)

SQLite UPDATE field in one table based on foreign key of another table

As in this question (SQLite field with a list of foreign keys), I'm trying to keep my real estate agents and listings in an SQLite DB with python.
I did as suggested and now have tables that look like this:
CREATE TABLE listings(
listing_id INTEGER PRIMARY KEY AUTOINCREMENT,
listing_address TEXT UNIQUE NOT NULL,
acq_date DATE
agent_id INTEGER,
FOREIGN KEY (agent_id) REFERENCES agent (agent_id)
)
CREATE TABLE agent(
agent_id INTEGER PRIMARY KEY AUTOINCREMENT,
agent_name TEXT NOT NULL,
agent_last_request TEXT
)
I am now trying to update the agent table based on calculations done from the listing. My theory is that there must be a one-line-of-sql way to update a field using the foreign key from another table's row. I already have this working, in fact:
given my_listing_id
given new_request_data
"SELECT agent_id FROM listings WHERE listing_id = ?", (my_listing_id,)
fetch etc..
"UPDATE agent SET agent_last_request = ? WHERE agent_id = ?", (new_request_data, agent_id)
But in the interest of doing this right, it seems to me that there should be one line of SQL that uses the foreign key to update another table. I tried stuff like this, but failed:
"UPDATE agent, listings SET agent_last_request = ? WHERE agent.agent_id = listings.agent_id AND listings.agent_id = ?", (new_request_data, my_listing_id)
So how do I update agent_last_request when I have my_listing_id? Should I keep doing it the long way?
To look up a single value, you can use a scalar subquery:
UPDATE agent
SET agent_last_request = ?
WHERE agent_id = (SELECT agent_id
FROM listings
WHERE listing_id = ?)

How to achieve that every record in two tables have different id?

I have two tables inherited from base table ( SQLALCHEMY models)
class Base(object):
def __tablename__(self):
return self.__name__.lower()
id = Column(Integer, primary_key=True, nullable=False)
utc_time = Column(Integer, default=utc_time(), onupdate=utc_time())
datetime = Column(TIMESTAMP, server_default=func.now(), onupdate=func.current_timestamp())
and inherited tables Person and Data
How to achieve that every Person and Data have different id, every id to be unique for two tables ? ( Person when generate of id to be aware of Data ids and vice versa)
if you're using Postgresql, Firebird, or Oracle, use a sequence that's independent of both tables to generate primary key values. Otherwise, you need to roll some manual process like an "id" table or something like that - this can be tricky to do atomically.
Basically if I were given this problem, I'd ask why exactly would two tables need unique primary key values like that - if the primary key is an autoincrementing integer, that indicates it's meaningless. It's only purpose is to provide a unique key into a single table.

Categories

Resources